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 : : // SPDX-FileCopyrightText: 2012 Red Hat, Inc.
5 : :
6 : : #pragma once
7 : :
8 : : #include <config.h>
9 : :
10 : : #include <glib-object.h>
11 : : #include <glib.h>
12 : :
13 : : #include <js/CallArgs.h>
14 : : #include <js/RootingAPI.h>
15 : : #include <js/TypeDecls.h>
16 : : #include <mozilla/Maybe.h>
17 : :
18 : : #include "gi/cwrapper.h"
19 : : #include "gi/info.h"
20 : : #include "gi/wrapperutils.h"
21 : : #include "gjs/jsapi-util.h"
22 : : #include "gjs/macros.h"
23 : : #include "util/log.h"
24 : :
25 : : class InterfacePrototype;
26 : : class InterfaceInstance;
27 : : struct JSFunctionSpec;
28 : :
29 : : /* For more information on this Base/Prototype/Interface scheme, see the notes
30 : : * in wrapperutils.h.
31 : : *
32 : : * What's unusual about this subclass is that InterfaceInstance should never
33 : : * actually be instantiated. Interfaces can't be constructed, and
34 : : * GIWrapperBase::constructor() is overridden to just throw an exception and not
35 : : * create any JS wrapper object.
36 : : *
37 : : * We use the template classes from wrapperutils.h anyway, because there is
38 : : * still a lot of common code.
39 : : */
40 : :
41 : : class InterfaceBase : public GIWrapperBase<InterfaceBase, InterfacePrototype,
42 : : InterfaceInstance> {
43 : : friend class CWrapperPointerOps<InterfaceBase>;
44 : : friend class GIWrapperBase<InterfaceBase, InterfacePrototype,
45 : : InterfaceInstance>;
46 : :
47 : : protected:
48 : 273 : explicit InterfaceBase(InterfacePrototype* proto = nullptr)
49 : 273 : : GIWrapperBase(proto) {}
50 : :
51 : : static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_GINTERFACE;
52 : : static constexpr const char* DEBUG_TAG = "interface";
53 : :
54 : : static const struct JSClassOps class_ops;
55 : : static const struct JSClass klass;
56 : : static JSFunctionSpec static_methods[];
57 : :
58 : : // JSNative methods
59 : :
60 : : // Overrides GIWrapperBase::constructor().
61 : : GJS_JSAPI_RETURN_CONVENTION
62 : 1 : static bool constructor(JSContext* cx, unsigned argc, JS::Value* vp) {
63 : 1 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
64 : 1 : gjs_throw_abstract_constructor_error(cx, args);
65 : 1 : return false;
66 : : }
67 : :
68 : : GJS_JSAPI_RETURN_CONVENTION
69 : : static bool has_instance(JSContext*, unsigned, JS::Value*);
70 : : };
71 : :
72 : : class InterfacePrototype
73 : : : public GIWrapperPrototype<InterfaceBase, InterfacePrototype,
74 : : InterfaceInstance,
75 : : mozilla::Maybe<GI::AutoInterfaceInfo>,
76 : : mozilla::Maybe<GI::InterfaceInfo>> {
77 : : friend class GIWrapperPrototype<InterfaceBase, InterfacePrototype,
78 : : InterfaceInstance,
79 : : mozilla::Maybe<GI::AutoInterfaceInfo>,
80 : : mozilla::Maybe<GI::InterfaceInfo>>;
81 : : friend class GIWrapperBase<InterfaceBase, InterfacePrototype,
82 : : InterfaceInstance>;
83 : : friend class InterfaceBase; // for has_instance_impl
84 : :
85 : : // the GTypeInterface vtable wrapped by this JS object
86 : : GTypeInterface* m_vtable;
87 : :
88 : : explicit InterfacePrototype(const mozilla::Maybe<const GI::InterfaceInfo>&,
89 : : GType);
90 : : ~InterfacePrototype();
91 : :
92 : : // JSClass operations
93 : :
94 : : GJS_JSAPI_RETURN_CONVENTION
95 : : bool resolve_impl(JSContext*, JS::HandleObject, JS::HandleId,
96 : : bool* resolved);
97 : :
98 : : GJS_JSAPI_RETURN_CONVENTION
99 : : bool new_enumerate_impl(JSContext*, JS::HandleObject,
100 : : JS::MutableHandleIdVector properties,
101 : : bool only_enumerable);
102 : :
103 : : // JS methods
104 : :
105 : : GJS_JSAPI_RETURN_CONVENTION
106 : : bool has_instance_impl(JSContext*, const JS::CallArgs&);
107 : : };
108 : :
109 : : class InterfaceInstance
110 : : : public GIWrapperInstance<InterfaceBase, InterfacePrototype,
111 : : InterfaceInstance> {
112 : : friend class GIWrapperInstance<InterfaceBase, InterfacePrototype,
113 : : InterfaceInstance>;
114 : : friend class GIWrapperBase<InterfaceBase, InterfacePrototype,
115 : : InterfaceInstance>;
116 : :
117 : : [[noreturn]] InterfaceInstance(InterfacePrototype* prototype,
118 : : JS::HandleObject obj)
119 : : : GIWrapperInstance(prototype, obj) {
120 : : g_assert_not_reached();
121 : : }
122 : : [[noreturn]] ~InterfaceInstance() { g_assert_not_reached(); }
123 : : };
124 : :
125 : : GJS_JSAPI_RETURN_CONVENTION
126 : : bool gjs_lookup_interface_constructor(JSContext*, GType,
127 : : JS::MutableHandleValue);
|