1use 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), 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}