LCOV - code coverage report
Current view: top level - gi - object.h (source / functions) Coverage Total Hit
Test: gjs- Code Coverage Lines: 77.5 % 40 31
Test Date: 2025-05-07 12:25:00 Functions: 88.2 % 17 15
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 50.0 % 10 5

             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_OBJECT_H_
       6                 :             : #define GI_OBJECT_H_
       7                 :             : 
       8                 :             : #include <config.h>
       9                 :             : 
      10                 :             : #include <stddef.h>  // for size_t
      11                 :             : #include <stdint.h>  // for uint32_t
      12                 :             : 
      13                 :             : #include <functional>
      14                 :             : #include <unordered_set>
      15                 :             : #include <vector>
      16                 :             : 
      17                 :             : #include <girepository.h>
      18                 :             : #include <glib-object.h>
      19                 :             : #include <glib.h>
      20                 :             : 
      21                 :             : #include <js/AllocPolicy.h>
      22                 :             : #include <js/GCHashTable.h>  // for GCHashMap
      23                 :             : #include <js/HashTable.h>    // for DefaultHasher
      24                 :             : #include <js/Id.h>
      25                 :             : #include <js/PropertySpec.h>
      26                 :             : #include <js/RootingAPI.h>
      27                 :             : #include <js/TypeDecls.h>
      28                 :             : #include <mozilla/HashFunctions.h>  // for HashGeneric, HashNumber
      29                 :             : #include <mozilla/Likely.h>         // for MOZ_LIKELY
      30                 :             : #include <mozilla/Maybe.h>
      31                 :             : 
      32                 :             : #include "gi/info.h"
      33                 :             : #include "gi/value.h"
      34                 :             : #include "gi/wrapperutils.h"
      35                 :             : #include "gjs/auto.h"
      36                 :             : #include "gjs/jsapi-util-root.h"
      37                 :             : #include "gjs/jsapi-util.h"  // for gjs_throw
      38                 :             : #include "gjs/macros.h"
      39                 :             : #include "util/log.h"
      40                 :             : 
      41                 :             : class GjsAtoms;
      42                 :             : class JSTracer;
      43                 :             : namespace JS {
      44                 :             : class CallArgs;
      45                 :             : }
      46                 :             : namespace Gjs {
      47                 :             : namespace Test {
      48                 :             : struct ObjectInstance;
      49                 :             : }
      50                 :             : }
      51                 :             : class ObjectInstance;
      52                 :             : class ObjectPrototype;
      53                 :             : class ObjectPropertyInfoCaller;
      54                 :             : class ObjectPropertyPspecCaller;
      55                 :             : 
      56                 :             : /*
      57                 :             :  * ObjectBase:
      58                 :             :  *
      59                 :             :  * Specialization of GIWrapperBase for GObject instances. See the documentation
      60                 :             :  * in wrapperutils.h.
      61                 :             :  *
      62                 :             :  * It's important that ObjectBase and ObjectInstance not grow in size without a
      63                 :             :  * very good reason. There can be tens, maybe hundreds of thousands of these
      64                 :             :  * objects alive in a typical gnome-shell run, so even 8 more bytes will add up.
      65                 :             :  * It's less critical that ObjectPrototype stay small, since only one of these
      66                 :             :  * is allocated per GType.
      67                 :             :  */
      68                 :             : class ObjectBase
      69                 :             :     : public GIWrapperBase<ObjectBase, ObjectPrototype, ObjectInstance> {
      70                 :             :     friend class GIWrapperBase<ObjectBase, ObjectPrototype, ObjectInstance>;
      71                 :             : 
      72                 :             :  protected:
      73                 :        2450 :     explicit ObjectBase(ObjectPrototype* proto = nullptr)
      74                 :        2450 :         : GIWrapperBase(proto) {}
      75                 :             : 
      76                 :             :  public:
      77                 :             :     using SignalMatchFunc = guint(gpointer, GSignalMatchType, guint, GQuark,
      78                 :             :                                   GClosure*, gpointer, gpointer);
      79                 :             :     static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_GOBJECT;
      80                 :             :     static constexpr const char* DEBUG_TAG = "GObject";
      81                 :             : 
      82                 :             :     static const struct JSClassOps class_ops;
      83                 :             :     static const struct JSClass klass;
      84                 :             :     static JSFunctionSpec proto_methods[];
      85                 :             :     static JSPropertySpec proto_properties[];
      86                 :             : 
      87                 :             :     static GObject* to_c_ptr(JSContext* cx, JS::HandleObject obj) = delete;
      88                 :             :     GJS_JSAPI_RETURN_CONVENTION
      89                 :             :     static bool to_c_ptr(JSContext* cx, JS::HandleObject obj, GObject** ptr);
      90                 :             :     GJS_JSAPI_RETURN_CONVENTION
      91                 :             :     static bool transfer_to_gi_argument(JSContext* cx, JS::HandleObject obj,
      92                 :             :                                         GIArgument* arg,
      93                 :             :                                         GIDirection transfer_direction,
      94                 :             :                                         GITransfer transfer_ownership,
      95                 :             :                                         GType expected_gtype);
      96                 :             : 
      97                 :             :  private:
      98                 :             :     // This is used in debug methods only.
      99                 :             :     [[nodiscard]] const void* jsobj_addr() const;
     100                 :             : 
     101                 :             :     /* Helper methods */
     102                 :             : 
     103                 :             :  protected:
     104                 :        7916 :     void debug_lifecycle(const char* message) const {
     105                 :        7916 :         GIWrapperBase::debug_lifecycle(jsobj_addr(), message);
     106                 :        7916 :     }
     107                 :             : 
     108                 :             :     [[nodiscard]] bool id_is_never_lazy(jsid name, const GjsAtoms& atoms);
     109                 :             :     [[nodiscard]] bool is_custom_js_class();
     110                 :             : 
     111                 :             :  public:
     112                 :             :     // Overrides GIWrapperBase::typecheck(). We only override the overload that
     113                 :             :     // throws, so that we can throw our own more informative error.
     114                 :             :     template <typename T>
     115                 :        2117 :     GJS_JSAPI_RETURN_CONVENTION static bool typecheck(JSContext* cx,
     116                 :             :                                                       JS::HandleObject obj,
     117                 :             :                                                       T expected) {
     118         [ +  + ]:        2117 :         if (GIWrapperBase::typecheck(cx, obj, expected))
     119                 :        2112 :             return true;
     120                 :             : 
     121                 :           5 :         gjs_throw(cx,
     122                 :             :                   "This JS object wrapper isn't wrapping a GObject."
     123                 :             :                   " If this is a custom subclass, are you sure you chained"
     124                 :             :                   " up to the parent _init properly?");
     125                 :           5 :         return false;
     126                 :             :     }
     127                 :             :     template <typename T>
     128                 :             :     [[nodiscard]]
     129                 :          17 :     static bool typecheck(JSContext* cx, JS::HandleObject obj, T expected,
     130                 :             :                           GjsTypecheckNoThrow no_throw) {
     131                 :          17 :         return GIWrapperBase::typecheck(cx, obj, expected, no_throw);
     132                 :             :     }
     133                 :             : 
     134                 :             :     /* JSClass operations */
     135                 :             : 
     136                 :             :     static bool add_property(JSContext* cx, JS::HandleObject obj,
     137                 :             :                              JS::HandleId id, JS::HandleValue value);
     138                 :             : 
     139                 :             :     /* JS property getters/setters */
     140                 :             : 
     141                 :             :  public:
     142                 :             :     template <typename TAG = void>
     143                 :             :     GJS_JSAPI_RETURN_CONVENTION static bool prop_getter(JSContext*, unsigned,
     144                 :             :                                                         JS::Value*);
     145                 :             :     GJS_JSAPI_RETURN_CONVENTION
     146                 :             :     static bool prop_getter_write_only(JSContext*, unsigned argc,
     147                 :             :                                        JS::Value* vp);
     148                 :             :     GJS_JSAPI_RETURN_CONVENTION
     149                 :             :     static bool prop_getter_func(JSContext* cx, unsigned argc, JS::Value* vp);
     150                 :             :     template <typename TAG, GITransfer TRANSFER = GI_TRANSFER_NOTHING>
     151                 :             :     GJS_JSAPI_RETURN_CONVENTION static bool prop_getter_simple_type_func(
     152                 :             :         JSContext*, unsigned argc, JS::Value* vp);
     153                 :             :     GJS_JSAPI_RETURN_CONVENTION
     154                 :             :     static bool field_getter(JSContext* cx, unsigned argc, JS::Value* vp);
     155                 :             :     template <typename TAG = void>
     156                 :             :     GJS_JSAPI_RETURN_CONVENTION static bool prop_setter(JSContext*, unsigned,
     157                 :             :                                                         JS::Value*);
     158                 :             :     GJS_JSAPI_RETURN_CONVENTION
     159                 :             :     static bool prop_setter_read_only(JSContext*, unsigned argc, JS::Value* vp);
     160                 :             :     GJS_JSAPI_RETURN_CONVENTION
     161                 :             :     static bool prop_setter_func(JSContext* cx, unsigned argc, JS::Value* vp);
     162                 :             :     template <typename TAG, GITransfer TRANSFER = GI_TRANSFER_NOTHING>
     163                 :             :     GJS_JSAPI_RETURN_CONVENTION static bool prop_setter_simple_type_func(
     164                 :             :         JSContext*, unsigned argc, JS::Value* vp);
     165                 :             :     GJS_JSAPI_RETURN_CONVENTION
     166                 :             :     static bool field_setter(JSContext* cx, unsigned argc, JS::Value* vp);
     167                 :             : 
     168                 :             :     /* JS methods */
     169                 :             : 
     170                 :             :     GJS_JSAPI_RETURN_CONVENTION
     171                 :             :     static bool connect(JSContext* cx, unsigned argc, JS::Value* vp);
     172                 :             :     GJS_JSAPI_RETURN_CONVENTION
     173                 :             :     static bool connect_after(JSContext* cx, unsigned argc, JS::Value* vp);
     174                 :             :     GJS_JSAPI_RETURN_CONVENTION
     175                 :             :     static bool connect_object(JSContext* cx, unsigned argc, JS::Value* vp);
     176                 :             :     GJS_JSAPI_RETURN_CONVENTION
     177                 :             :     static bool emit(JSContext* cx, unsigned argc, JS::Value* vp);
     178                 :             :     GJS_JSAPI_RETURN_CONVENTION
     179                 :             :     static bool signal_find(JSContext* cx, unsigned argc, JS::Value* vp);
     180                 :             :     template <SignalMatchFunc(*MATCH_FUNC)>
     181                 :             :     GJS_JSAPI_RETURN_CONVENTION static bool signals_action(JSContext* cx,
     182                 :             :                                                            unsigned argc,
     183                 :             :                                                            JS::Value* vp);
     184                 :             :     GJS_JSAPI_RETURN_CONVENTION
     185                 :             :     static bool to_string(JSContext* cx, unsigned argc, JS::Value* vp);
     186                 :             :     GJS_JSAPI_RETURN_CONVENTION
     187                 :             :     static bool init_gobject(JSContext* cx, unsigned argc, JS::Value* vp);
     188                 :             :     GJS_JSAPI_RETURN_CONVENTION
     189                 :             :     static bool hook_up_vfunc(JSContext* cx, unsigned argc, JS::Value* vp);
     190                 :             : 
     191                 :             :     /* Quarks */
     192                 :             : 
     193                 :             :  protected:
     194                 :             :     [[nodiscard]] static GQuark instance_strings_quark();
     195                 :             : 
     196                 :             :  public:
     197                 :             :     [[nodiscard]] static GQuark custom_type_quark();
     198                 :             :     [[nodiscard]] static GQuark custom_property_quark();
     199                 :             :     [[nodiscard]] static GQuark disposed_quark();
     200                 :             : };
     201                 :             : 
     202                 :             : // See https://bugzilla.mozilla.org/show_bug.cgi?id=1614220
     203                 :             : struct IdHasher {
     204                 :             :     typedef jsid Lookup;
     205                 :       14362 :     static mozilla::HashNumber hash(jsid id) {
     206         [ +  + ]:       14362 :         if (MOZ_LIKELY(id.isString()))
     207                 :       13830 :             return js::DefaultHasher<JSString*>::hash(id.toString());
     208         [ +  - ]:         532 :         if (id.isSymbol())
     209                 :         532 :             return js::DefaultHasher<JS::Symbol*>::hash(id.toSymbol());
     210                 :           0 :         return mozilla::HashGeneric(id.asRawBits());
     211                 :             :     }
     212                 :        6882 :     static bool match(jsid id1, jsid id2) { return id1 == id2; }
     213                 :             : };
     214                 :             : 
     215                 :             : class ObjectPrototype
     216                 :             :     : public GIWrapperPrototype<ObjectBase, ObjectPrototype, ObjectInstance> {
     217                 :             :     friend class GIWrapperPrototype<ObjectBase, ObjectPrototype,
     218                 :             :                                     ObjectInstance>;
     219                 :             :     friend class GIWrapperBase<ObjectBase, ObjectPrototype, ObjectInstance>;
     220                 :             : 
     221                 :             :     using NegativeLookupCache =
     222                 :             :         JS::GCHashSet<JS::Heap<jsid>, IdHasher, js::SystemAllocPolicy>;
     223                 :             : 
     224                 :             :     NegativeLookupCache m_unresolvable_cache;
     225                 :             :     // a list of vfunc GClosures installed on this prototype, used when tracing
     226                 :             :     std::unordered_set<GClosure*> m_vfuncs;
     227                 :             :     // a list of interface types explicitly associated with this prototype,
     228                 :             :     // by gjs_add_interface
     229                 :             :     std::vector<GType> m_interface_gtypes;
     230                 :             : 
     231                 :             :     ObjectPrototype(GIObjectInfo* info, GType gtype);
     232                 :             :     ~ObjectPrototype();
     233                 :             : 
     234                 :             :     static constexpr InfoType::Tag info_type_tag = InfoType::Object;
     235                 :             : 
     236                 :             :  public:
     237                 :             :     [[nodiscard]] static ObjectPrototype* for_gtype(GType gtype);
     238                 :             : 
     239                 :             :     /* Helper methods */
     240                 :             :  private:
     241                 :             :     GJS_JSAPI_RETURN_CONVENTION
     242                 :             :     bool get_parent_proto(JSContext* cx, JS::MutableHandleObject proto) const;
     243                 :             :     GJS_JSAPI_RETURN_CONVENTION
     244                 :             :     bool get_parent_constructor(JSContext* cx,
     245                 :             :                                 JS::MutableHandleObject constructor) const;
     246                 :             : 
     247                 :             :     [[nodiscard]] bool is_vfunc_unchanged(GIVFuncInfo* info);
     248                 :             :     static void vfunc_invalidated_notify(void* data, GClosure* closure);
     249                 :             : 
     250                 :             :     GJS_JSAPI_RETURN_CONVENTION
     251                 :             :     bool lazy_define_gobject_property(
     252                 :             :         JSContext* cx, JS::HandleObject obj, JS::HandleId id, GParamSpec*,
     253                 :             :         bool* resolved, const char* name,
     254                 :             :         mozilla::Maybe<const GI::AutoPropertyInfo> = {});
     255                 :             : 
     256                 :             :     enum ResolveWhat { ConsiderOnlyMethods, ConsiderMethodsAndProperties };
     257                 :             :     GJS_JSAPI_RETURN_CONVENTION
     258                 :             :     bool resolve_no_info(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
     259                 :             :                          bool* resolved, const char* name,
     260                 :             :                          ResolveWhat resolve_props);
     261                 :             :     GJS_JSAPI_RETURN_CONVENTION
     262                 :             :     bool uncached_resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
     263                 :             :                           const char* name, bool* resolved);
     264                 :             : 
     265                 :             :  public:
     266                 :             :     void set_interfaces(GType* interface_gtypes, uint32_t n_interface_gtypes);
     267                 :             :     void set_type_qdata(void);
     268                 :             :     GJS_JSAPI_RETURN_CONVENTION
     269                 :             :     GParamSpec* find_param_spec_from_id(JSContext*,
     270                 :             :                                         Gjs::AutoTypeClass<GObjectClass> const&,
     271                 :             :                                         JS::HandleString key);
     272                 :             :     GJS_JSAPI_RETURN_CONVENTION
     273                 :             :     bool props_to_g_parameters(JSContext*,
     274                 :             :                                Gjs::AutoTypeClass<GObjectClass> const&,
     275                 :             :                                JS::HandleObject props,
     276                 :             :                                std::vector<const char*>* names,
     277                 :             :                                AutoGValueVector* values);
     278                 :             : 
     279                 :             :     GJS_JSAPI_RETURN_CONVENTION
     280                 :             :     static bool define_class(JSContext* cx, JS::HandleObject in_object,
     281                 :             :                              GIObjectInfo* info, GType gtype,
     282                 :             :                              GType* interface_gtypes,
     283                 :             :                              uint32_t n_interface_gtypes,
     284                 :             :                              JS::MutableHandleObject constructor,
     285                 :             :                              JS::MutableHandleObject prototype);
     286                 :             : 
     287                 :           0 :     void ref_vfuncs(void) {
     288         [ #  # ]:           0 :         for (GClosure* closure : m_vfuncs)
     289                 :           0 :             g_closure_ref(closure);
     290                 :           0 :     }
     291                 :           0 :     void unref_vfuncs(void) {
     292         [ #  # ]:           0 :         for (GClosure* closure : m_vfuncs)
     293                 :           0 :             g_closure_unref(closure);
     294                 :           0 :     }
     295                 :             : 
     296                 :             :     /* JSClass operations */
     297                 :             :  private:
     298                 :             :     GJS_JSAPI_RETURN_CONVENTION
     299                 :             :     bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
     300                 :             :                       bool* resolved);
     301                 :             : 
     302                 :             :     GJS_JSAPI_RETURN_CONVENTION
     303                 :             :     bool new_enumerate_impl(JSContext* cx, JS::HandleObject obj,
     304                 :             :                             JS::MutableHandleIdVector properties,
     305                 :             :                             bool only_enumerable);
     306                 :             :     void trace_impl(JSTracer* tracer);
     307                 :             : 
     308                 :             :     /* JS methods */
     309                 :             :  public:
     310                 :             :     GJS_JSAPI_RETURN_CONVENTION
     311                 :             :     bool hook_up_vfunc_impl(JSContext* cx, const JS::CallArgs& args);
     312                 :             : };
     313                 :             : 
     314                 :             : class ObjectInstance : public GIWrapperInstance<ObjectBase, ObjectPrototype,
     315                 :             :                                                 ObjectInstance, GObject> {
     316                 :             :     friend class GIWrapperInstance<ObjectBase, ObjectPrototype, ObjectInstance,
     317                 :             :                                    GObject>;
     318                 :             :     friend class GIWrapperBase<ObjectBase, ObjectPrototype, ObjectInstance>;
     319                 :             :     friend class ObjectBase;  // for add_property, prop_getter, etc.
     320                 :             :     friend struct Gjs::Test::ObjectInstance;
     321                 :             : 
     322                 :             :     // GIWrapperInstance::m_ptr may be null in ObjectInstance.
     323                 :             : 
     324                 :             :     GjsMaybeOwned m_wrapper;
     325                 :             :     // a list of all GClosures installed on this object (from signal connections
     326                 :             :     // and scope-notify callbacks passed to methods), used when tracing
     327                 :             :     std::vector<GClosure*> m_closures;
     328                 :             : 
     329                 :             :     bool m_wrapper_finalized : 1;
     330                 :             :     bool m_gobj_disposed : 1;
     331                 :             :     bool m_gobj_finalized : 1;
     332                 :             : 
     333                 :             :     /* True if this object has visible JS state, and thus its lifecycle is
     334                 :             :      * managed using toggle references. False if this object just keeps a
     335                 :             :      * hard ref on the underlying GObject, and may be finalized at will. */
     336                 :             :     bool m_uses_toggle_ref : 1;
     337                 :             : 
     338                 :             :     static bool s_weak_pointer_callback;
     339                 :             : 
     340                 :             :     /* Constructors */
     341                 :             : 
     342                 :             :  private:
     343                 :             :     ObjectInstance(ObjectPrototype* prototype, JS::HandleObject obj);
     344                 :             :     ~ObjectInstance();
     345                 :             : 
     346                 :             :     GJS_JSAPI_RETURN_CONVENTION
     347                 :             :     static ObjectInstance* new_for_gobject(JSContext* cx, GObject* gobj);
     348                 :             : 
     349                 :             :     // Extra method to get an existing ObjectInstance from qdata
     350                 :             : 
     351                 :             :  public:
     352                 :             :     [[nodiscard]] static ObjectInstance* for_gobject(GObject* gobj);
     353                 :             : 
     354                 :             :     /* Accessors */
     355                 :             : 
     356                 :             :  private:
     357                 :        3353 :     [[nodiscard]] bool has_wrapper() const { return !!m_wrapper; }
     358                 :             : 
     359                 :             :  public:
     360                 :        3060 :     [[nodiscard]] JSObject* wrapper() const { return m_wrapper.get(); }
     361                 :             : 
     362                 :             :     /* Methods to manipulate the JS object wrapper */
     363                 :             : 
     364                 :             :  private:
     365                 :        1990 :     void discard_wrapper(void) { m_wrapper.reset(); }
     366                 :        1637 :     void switch_to_rooted(JSContext* cx) { m_wrapper.switch_to_rooted(cx); }
     367                 :        1496 :     void switch_to_unrooted(JSContext* cx) { m_wrapper.switch_to_unrooted(cx); }
     368                 :        1698 :     [[nodiscard]] bool update_after_gc(JSTracer* trc) {
     369                 :        1698 :         return m_wrapper.update_after_gc(trc);
     370                 :             :     }
     371                 :        9760 :     [[nodiscard]] bool wrapper_is_rooted() const { return m_wrapper.rooted(); }
     372                 :             :     void release_native_object(void);
     373                 :             :     void associate_js_gobject(JSContext* cx, JS::HandleObject obj,
     374                 :             :                               GObject* gobj);
     375                 :             :     void disassociate_js_gobject(void);
     376                 :             :     void handle_context_dispose(void);
     377                 :             :     [[nodiscard]] bool weak_pointer_was_finalized(JSTracer* trc);
     378                 :             :     static void ensure_weak_pointer_callback(JSContext* cx);
     379                 :             :     static void update_heap_wrapper_weak_pointers(JSTracer* trc,
     380                 :             :                                                   JS::Compartment*, void* data);
     381                 :             : 
     382                 :             :  public:
     383                 :             :     void toggle_down(void);
     384                 :             :     void toggle_up(void);
     385                 :             : 
     386                 :             :     GJS_JSAPI_RETURN_CONVENTION
     387                 :             :     static JSObject* wrapper_from_gobject(JSContext* cx, GObject* ptr);
     388                 :             : 
     389                 :             :     GJS_JSAPI_RETURN_CONVENTION
     390                 :             :     static bool set_value_from_gobject(JSContext* cx, GObject*,
     391                 :             :                                        JS::MutableHandleValue);
     392                 :             : 
     393                 :             :     /* Methods to manipulate the list of closures */
     394                 :             : 
     395                 :             :  private:
     396                 :             :     void invalidate_closures();
     397                 :             :     static void closure_invalidated_notify(void* data, GClosure* closure);
     398                 :             : 
     399                 :             :  public:
     400                 :             :     GJS_JSAPI_RETURN_CONVENTION bool associate_closure(JSContext*, GClosure*);
     401                 :             : 
     402                 :             :     /* Helper methods */
     403                 :             : 
     404                 :             :  private:
     405                 :             :     void set_object_qdata(void);
     406                 :             :     void unset_object_qdata(void);
     407                 :             :     void track_gobject_finalization();
     408                 :             :     void ignore_gobject_finalization();
     409                 :             :     void check_js_object_finalized(void);
     410                 :             :     void ensure_uses_toggle_ref(JSContext*);
     411                 :             :     [[nodiscard]] bool check_gobject_disposed_or_finalized(
     412                 :             :         const char* for_what) const;
     413                 :             :     [[nodiscard]] bool check_gobject_finalized(const char* for_what) const;
     414                 :             :     GJS_JSAPI_RETURN_CONVENTION
     415                 :             :     bool signal_match_arguments_from_object(
     416                 :             :         JSContext* cx, JS::HandleObject props_obj, GSignalMatchType* mask_out,
     417                 :             :         unsigned* signal_id_out, GQuark* detail_out,
     418                 :             :         JS::MutableHandleObject callable_out);
     419                 :             : 
     420                 :             :  public:
     421                 :          58 :     static GObject* copy_ptr(JSContext*, GType, void* ptr) {
     422                 :          58 :         return G_OBJECT(g_object_ref(G_OBJECT(ptr)));
     423                 :             :     }
     424                 :             : 
     425                 :             :     GJS_JSAPI_RETURN_CONVENTION
     426                 :             :     bool init_custom_class_from_gobject(JSContext* cx, JS::HandleObject wrapper,
     427                 :             :                                         GObject* gobj);
     428                 :             : 
     429                 :             :     static void associate_string(GObject* obj, char* str);
     430                 :             : 
     431                 :             :     /* Methods to manipulate the linked list of instances */
     432                 :             : 
     433                 :             :  private:
     434                 :             :     static std::unordered_set<ObjectInstance*> s_wrapped_gobject_list;
     435                 :             :     void link(void);
     436                 :             :     void unlink(void);
     437                 :             :     [[nodiscard]] static size_t num_wrapped_gobjects() {
     438                 :             :         return s_wrapped_gobject_list.size();
     439                 :             :     }
     440                 :             :     using Action = std::function<void(ObjectInstance*)>;
     441                 :             :     using Predicate = std::function<bool(ObjectInstance*)>;
     442                 :             :     static void remove_wrapped_gobjects_if(const Predicate& predicate,
     443                 :             :                                            const Action& action);
     444                 :             : 
     445                 :             :  public:
     446                 :             :     static void prepare_shutdown(void);
     447                 :             : 
     448                 :             :     /* JSClass operations */
     449                 :             : 
     450                 :             :  private:
     451                 :             :     GJS_JSAPI_RETURN_CONVENTION
     452                 :             :     bool add_property_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
     453                 :             :                            JS::HandleValue value);
     454                 :             :     void finalize_impl(JS::GCContext*, JSObject* obj);
     455                 :             :     void trace_impl(JSTracer* trc);
     456                 :             : 
     457                 :             :     /* JS property getters/setters */
     458                 :             : 
     459                 :             :  private:
     460                 :             :     template <typename TAG>
     461                 :             :     GJS_JSAPI_RETURN_CONVENTION bool prop_getter_impl(
     462                 :             :         JSContext* cx, GParamSpec*, JS::MutableHandleValue rval);
     463                 :             :     GJS_JSAPI_RETURN_CONVENTION
     464                 :             :     bool prop_getter_impl(JSContext* cx, ObjectPropertyInfoCaller*,
     465                 :             :                           JS::CallArgs const& args);
     466                 :             :     template <typename TAG, GITransfer TRANSFER = GI_TRANSFER_NOTHING>
     467                 :             :     GJS_JSAPI_RETURN_CONVENTION bool prop_getter_impl(
     468                 :             :         JSContext*, ObjectPropertyPspecCaller*, JS::CallArgs const&);
     469                 :             :     GJS_JSAPI_RETURN_CONVENTION
     470                 :             :     bool field_getter_impl(JSContext* cx, GI::AutoFieldInfo const&,
     471                 :             :                            JS::MutableHandleValue rval);
     472                 :             :     template <typename TAG>
     473                 :             :     GJS_JSAPI_RETURN_CONVENTION bool prop_setter_impl(JSContext*, GParamSpec*,
     474                 :             :                                                       JS::HandleValue);
     475                 :             :     GJS_JSAPI_RETURN_CONVENTION
     476                 :             :     bool prop_setter_impl(JSContext* cx, ObjectPropertyInfoCaller*,
     477                 :             :                           JS::CallArgs const& args);
     478                 :             :     template <typename TAG, GITransfer TRANSFER = GI_TRANSFER_NOTHING>
     479                 :             :     GJS_JSAPI_RETURN_CONVENTION bool prop_setter_impl(
     480                 :             :         JSContext*, ObjectPropertyPspecCaller*, JS::CallArgs const&);
     481                 :             :     GJS_JSAPI_RETURN_CONVENTION
     482                 :             :     bool field_setter_not_impl(JSContext* cx, GI::AutoFieldInfo const&);
     483                 :             : 
     484                 :             :     // JS constructor
     485                 :             : 
     486                 :             :     GJS_JSAPI_RETURN_CONVENTION
     487                 :             :     bool constructor_impl(JSContext* cx, JS::HandleObject obj,
     488                 :             :                           const JS::CallArgs& args);
     489                 :             : 
     490                 :             :     /* JS methods */
     491                 :             : 
     492                 :             :  private:
     493                 :             :     GJS_JSAPI_RETURN_CONVENTION
     494                 :             :     bool connect_impl(JSContext* cx, const JS::CallArgs& args, bool after,
     495                 :             :                       bool object = false);
     496                 :             :     GJS_JSAPI_RETURN_CONVENTION
     497                 :             :     bool emit_impl(JSContext* cx, const JS::CallArgs& args);
     498                 :             :     GJS_JSAPI_RETURN_CONVENTION
     499                 :             :     bool signal_find_impl(JSContext* cx, const JS::CallArgs& args);
     500                 :             :     template <SignalMatchFunc(*MATCH_FUNC)>
     501                 :             :     GJS_JSAPI_RETURN_CONVENTION bool signals_action_impl(
     502                 :             :         JSContext* cx, const JS::CallArgs& args);
     503                 :             :     GJS_JSAPI_RETURN_CONVENTION
     504                 :             :     bool init_impl(JSContext* cx, const JS::CallArgs& args,
     505                 :             :                    JS::HandleObject obj);
     506                 :             :     [[nodiscard]] const char* to_string_kind() const;
     507                 :             : 
     508                 :             :     // Overrides GIWrapperInstance::typecheck_impl()
     509                 :             :     template <typename T>
     510                 :        2128 :     GJS_JSAPI_RETURN_CONVENTION bool typecheck_impl(T expected) const {
     511                 :        2128 :         g_assert(m_gobj_disposed || !m_ptr ||
     512                 :             :                  gtype() == G_OBJECT_TYPE(m_ptr.as<GObject*>()));
     513                 :        2128 :         return GIWrapperInstance::typecheck_impl(expected);
     514                 :             :     }
     515                 :             : 
     516                 :             :     /* Notification callbacks */
     517                 :             :     void gobj_dispose_notify(void);
     518                 :             :     static void wrapped_gobj_dispose_notify(void* data, GObject*);
     519                 :             :     static void wrapped_gobj_toggle_notify(void* instance, GObject* gobj,
     520                 :             :                                            gboolean is_last_ref);
     521                 :             : 
     522                 :             :  public:
     523                 :             :     static void context_dispose_notify(void* data,
     524                 :             :                                        GObject* where_the_object_was);
     525                 :             : };
     526                 :             : 
     527                 :             : GJS_JSAPI_RETURN_CONVENTION
     528                 :             : bool gjs_lookup_object_constructor(JSContext             *context,
     529                 :             :                                    GType                  gtype,
     530                 :             :                                    JS::MutableHandleValue value_p);
     531                 :             : 
     532                 :             : void gjs_object_clear_toggles(void);
     533                 :             : void gjs_object_shutdown_toggle_queue(void);
     534                 :             : 
     535                 :             : #endif  // GI_OBJECT_H_
        

Generated by: LCOV version 2.0-1