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_
|