Skip to main content

script_bindings/
init.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::ffi::c_char;
6use std::ptr;
7
8use js::jsapi::{
9    GCContext, Handle, JSAtomState, JSCLASS_RESERVED_SLOTS_SHIFT, JSClass, JSClassOps, JSContext,
10    JSObject, JSTracer, MutableHandleIdVector, PropertyKey,
11};
12use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_RESERVED_SLOTS_MASK};
13
14use crate::lock::ThreadUnsafeOnceLock;
15use crate::utils::{DOMClass, DOMJSClass};
16
17pub(crate) struct InitClassOpsConfig {
18    pub(crate) enumerate_hook: Option<
19        unsafe extern "C" fn(
20            *mut JSContext,
21            Handle<*mut JSObject>,
22            MutableHandleIdVector,
23            bool,
24        ) -> bool,
25    >,
26    pub(crate) resolve_hook: Option<
27        unsafe extern "C" fn(
28            *mut JSContext,
29            Handle<*mut JSObject>,
30            Handle<PropertyKey>,
31            *mut bool,
32        ) -> bool,
33    >,
34    pub(crate) may_resolve_hook:
35        Option<unsafe extern "C" fn(*const JSAtomState, PropertyKey, *mut JSObject) -> bool>,
36    pub(crate) finalize_hook: unsafe extern "C" fn(*mut GCContext, *mut JSObject),
37    pub(crate) trace_hook: unsafe extern "C" fn(*mut JSTracer, *mut JSObject),
38}
39
40pub(crate) struct DomJSClassConfig {
41    pub(crate) name: *const c_char,
42    pub(crate) flags: u32,
43    pub(crate) slots: u32,
44    pub(crate) class: DOMClass,
45}
46
47pub(crate) fn init_domjs_class(
48    js_class: &ThreadUnsafeOnceLock<JSClassOps>,
49    js_class_config: InitClassOpsConfig,
50    class: &ThreadUnsafeOnceLock<DOMJSClass>,
51    domjs_class_config: DomJSClassConfig,
52) {
53    js_class.set(JSClassOps {
54        addProperty: None,
55        delProperty: None,
56        enumerate: None,
57        newEnumerate: js_class_config.enumerate_hook,
58        resolve: js_class_config.resolve_hook,
59        mayResolve: js_class_config.may_resolve_hook,
60        finalize: Some(js_class_config.finalize_hook),
61        call: None,
62        construct: None,
63        trace: Some(js_class_config.trace_hook),
64    });
65
66    class.set(DOMJSClass {
67        base: JSClass {
68            name: domjs_class_config.name,
69            flags: JSCLASS_IS_DOMJSCLASS |
70                domjs_class_config.flags |
71                (((domjs_class_config.slots) & JSCLASS_RESERVED_SLOTS_MASK) <<
72                    JSCLASS_RESERVED_SLOTS_SHIFT), /* JSCLASS_HAS_RESERVED_SLOTS({args['slots']}) */
73            cOps: unsafe { js_class.get() },
74            spec: ptr::null(),
75            ext: ptr::null(),
76            oOps: ptr::null(),
77        },
78        dom_class: domjs_class_config.class,
79    });
80}