LCOV - code coverage report
Current view: top level - gi - function.h (source / functions) Coverage Total Hit
Test: gjs- Code Coverage Lines: 100.0 % 37 37
Test Date: 2024-04-20 17:42:51 Functions: 100.0 % 13 13
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 80.0 % 20 16

             Branch data     Line data    Source code
       1                 :             : /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
       2                 :             : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
       3                 :             : // SPDX-FileCopyrightText: 2008 litl, LLC
       4                 :             : 
       5                 :             : #ifndef GI_FUNCTION_H_
       6                 :             : #define GI_FUNCTION_H_
       7                 :             : 
       8                 :             : #include <config.h>
       9                 :             : 
      10                 :             : #include <stdint.h>
      11                 :             : 
      12                 :             : #include <memory>  // for unique_ptr
      13                 :             : #include <unordered_set>
      14                 :             : #include <vector>
      15                 :             : 
      16                 :             : #include <ffi.h>
      17                 :             : #include <girepository.h>
      18                 :             : #include <girffi.h>  // for g_callable_info_get_closure_native_address
      19                 :             : #include <glib-object.h>
      20                 :             : #include <glib.h>
      21                 :             : 
      22                 :             : #include <js/GCVector.h>
      23                 :             : #include <js/RootingAPI.h>
      24                 :             : #include <js/TypeDecls.h>
      25                 :             : #include <js/Value.h>
      26                 :             : 
      27                 :             : #include "gi/closure.h"
      28                 :             : #include "gjs/jsapi-util.h"
      29                 :             : #include "gjs/macros.h"
      30                 :             : 
      31                 :             : namespace JS {
      32                 :             : class CallArgs;
      33                 :             : }
      34                 :             : 
      35                 :             : typedef enum {
      36                 :             :     PARAM_NORMAL,
      37                 :             :     PARAM_SKIPPED,
      38                 :             :     PARAM_ARRAY,
      39                 :             :     PARAM_CALLBACK,
      40                 :             :     PARAM_UNKNOWN,
      41                 :             : } GjsParamType;
      42                 :             : 
      43                 :             : using GjsAutoGClosure =
      44                 :             :     GjsAutoPointer<GClosure, GClosure, g_closure_unref, g_closure_ref>;
      45                 :             : 
      46                 :             : struct GjsCallbackTrampoline : public Gjs::Closure {
      47                 :             :     GJS_JSAPI_RETURN_CONVENTION static GjsCallbackTrampoline* create(
      48                 :             :         JSContext* cx, JS::HandleObject callable, GICallableInfo* callable_info,
      49                 :             :         GIScopeType scope, bool has_scope_object, bool is_vfunc);
      50                 :             : 
      51                 :             :     ~GjsCallbackTrampoline();
      52                 :             : 
      53                 :         295 :     void* closure() const {
      54                 :             : #if GI_CHECK_VERSION(1, 71, 0)
      55                 :         295 :         return g_callable_info_get_closure_native_address(m_info, m_closure);
      56                 :             : #else
      57                 :             :         return m_closure;
      58                 :             : #endif
      59                 :             :     }
      60                 :             : 
      61                 :         237 :     ffi_closure* get_ffi_closure() const {
      62                 :         237 :         return m_closure;
      63                 :             :     }
      64                 :             : 
      65                 :             :     void mark_forever();
      66                 :             : 
      67                 :             :     static void prepare_shutdown();
      68                 :             : 
      69                 :             :  private:
      70                 :             :     ffi_closure* create_closure();
      71                 :             :     GJS_JSAPI_RETURN_CONVENTION bool initialize();
      72                 :             :     GjsCallbackTrampoline(JSContext* cx, JS::HandleObject callable,
      73                 :             :                           GICallableInfo* callable_info, GIScopeType scope,
      74                 :             :                           bool has_scope_object, bool is_vfunc);
      75                 :             : 
      76                 :             :     void callback_closure(GIArgument** args, void* result);
      77                 :             :     GJS_JSAPI_RETURN_CONVENTION
      78                 :             :     bool callback_closure_inner(JSContext* cx, JS::HandleObject this_object,
      79                 :             :                                 GObject* gobject, JS::MutableHandleValue rval,
      80                 :             :                                 GIArgument** args, GITypeInfo* ret_type,
      81                 :             :                                 int n_args, int c_args_offset, void* result);
      82                 :             :     void warn_about_illegal_js_callback(const char* when, const char* reason,
      83                 :             :                                         bool dump_stack);
      84                 :             : 
      85                 :             :     static std::vector<GjsAutoGClosure> s_forever_closure_list;
      86                 :             : 
      87                 :             :     GjsAutoCallableInfo m_info;
      88                 :             :     ffi_closure* m_closure = nullptr;
      89                 :             :     std::unique_ptr<GjsParamType[]> m_param_types;
      90                 :             :     ffi_cif m_cif;
      91                 :             : 
      92                 :             :     GIScopeType m_scope : 3;
      93                 :             :     bool m_is_vfunc : 1;
      94                 :             : };
      95                 :             : 
      96                 :             : // Stack allocation only!
      97                 :             : class GjsFunctionCallState {
      98                 :             :     GjsAutoCppPointer<GIArgument[]> m_in_cvalues;
      99                 :             :     GjsAutoCppPointer<GIArgument[]> m_out_cvalues;
     100                 :             :     GjsAutoCppPointer<GIArgument[]> m_inout_original_cvalues;
     101                 :             : 
     102                 :             :  public:
     103                 :             :     std::unordered_set<GIArgument*> ignore_release;
     104                 :             :     JS::RootedObject instance_object;
     105                 :             :     JS::RootedVector<JS::Value> return_values;
     106                 :             :     GjsAutoError local_error;
     107                 :             :     GICallableInfo* info;
     108                 :             :     uint8_t gi_argc = 0;
     109                 :             :     uint8_t processed_c_args = 0;
     110                 :             :     bool failed : 1;
     111                 :             :     bool can_throw_gerror : 1;
     112                 :             :     bool is_method : 1;
     113                 :             : 
     114                 :       64461 :     GjsFunctionCallState(JSContext* cx, GICallableInfo* callable)
     115                 :       64461 :         : instance_object(cx),
     116                 :       64461 :           return_values(cx),
     117                 :       64461 :           info(callable),
     118                 :       64461 :           gi_argc(g_callable_info_get_n_args(callable)),
     119                 :       64461 :           failed(false),
     120                 :      128922 :           can_throw_gerror(g_callable_info_can_throw_gerror(callable)),
     121                 :      193383 :           is_method(g_callable_info_is_method(callable)) {
     122                 :       64461 :         int size = gi_argc + first_arg_offset();
     123         [ +  - ]:       64461 :         m_in_cvalues = new GIArgument[size];
     124         [ +  - ]:       64461 :         m_out_cvalues = new GIArgument[size];
     125         [ +  - ]:       64461 :         m_inout_original_cvalues = new GIArgument[size];
     126                 :       64461 :     }
     127                 :             : 
     128                 :             :     GjsFunctionCallState(const GjsFunctionCallState&) = delete;
     129                 :             :     GjsFunctionCallState& operator=(const GjsFunctionCallState&) = delete;
     130                 :             : 
     131         [ +  + ]:      610355 :     constexpr int first_arg_offset() const { return is_method ? 2 : 1; }
     132                 :             : 
     133                 :             :     // The list always contains the return value, and the arguments
     134                 :       70942 :     constexpr GIArgument* instance() {
     135         [ +  - ]:       70942 :         return is_method ? &m_in_cvalues[1] : nullptr;
     136                 :             :     }
     137                 :             : 
     138                 :      164494 :     constexpr GIArgument* return_value() { return &m_out_cvalues[0]; }
     139                 :             : 
     140                 :      143698 :     constexpr GIArgument& in_cvalue(int index) const {
     141                 :      143698 :         return m_in_cvalues[index + first_arg_offset()];
     142                 :             :     }
     143                 :             : 
     144                 :      144283 :     constexpr GIArgument& out_cvalue(int index) const {
     145                 :      144283 :         return m_out_cvalues[index + first_arg_offset()];
     146                 :             :     }
     147                 :             : 
     148                 :         105 :     constexpr GIArgument& inout_original_cvalue(int index) const {
     149                 :         105 :         return m_inout_original_cvalues[index + first_arg_offset()];
     150                 :             :     }
     151                 :             : 
     152                 :      164991 :     constexpr bool did_throw_gerror() const {
     153   [ +  +  +  + ]:      164991 :         return can_throw_gerror && local_error;
     154                 :             :     }
     155                 :             : 
     156   [ +  +  +  + ]:       36253 :     constexpr bool call_completed() { return !failed && !did_throw_gerror(); }
     157                 :             : 
     158                 :      128904 :     constexpr unsigned last_processed_index() {
     159                 :      128904 :         return first_arg_offset() + processed_c_args;
     160                 :             :     }
     161                 :             : 
     162                 :           3 :     [[nodiscard]] GjsAutoChar display_name() {
     163                 :           3 :         GIBaseInfo* container = g_base_info_get_container(info);  // !owned
     164         [ +  + ]:           3 :         if (container) {
     165                 :             :             return g_strdup_printf(
     166                 :             :                 "%s.%s.%s", g_base_info_get_namespace(container),
     167                 :           1 :                 g_base_info_get_name(container), g_base_info_get_name(info));
     168                 :             :         }
     169                 :             :         return g_strdup_printf("%s.%s", g_base_info_get_namespace(info),
     170                 :           2 :                                g_base_info_get_name(info));
     171                 :             :     }
     172                 :             : };
     173                 :             : 
     174                 :             : GJS_JSAPI_RETURN_CONVENTION
     175                 :             : JSObject *gjs_define_function(JSContext       *context,
     176                 :             :                               JS::HandleObject in_object,
     177                 :             :                               GType            gtype,
     178                 :             :                               GICallableInfo  *info);
     179                 :             : 
     180                 :             : GJS_JSAPI_RETURN_CONVENTION
     181                 :             : bool gjs_invoke_constructor_from_c(JSContext* cx, GIFunctionInfo* info,
     182                 :             :                                    JS::HandleObject this_obj,
     183                 :             :                                    const JS::CallArgs& args,
     184                 :             :                                    GIArgument* rvalue);
     185                 :             : 
     186                 :             : #endif  // GI_FUNCTION_H_
        

Generated by: LCOV version 2.0-1