script_bindings/
finalize.rs1use std::any::type_name;
8use std::{mem, ptr};
9
10use js::glue::JS_GetReservedSlot;
11use js::jsapi::JSObject;
12use js::jsval::UndefinedValue;
13use js::rust::GCMethods;
14
15use crate::DomObject;
16use crate::codegen::PrototypeList::PROTO_OR_IFACE_LENGTH;
17use crate::utils::{ProtoOrIfaceArray, get_proto_or_iface_array};
18use crate::weakref::{DOM_WEAK_SLOT, WeakBox, WeakReferenceable};
19
20unsafe fn do_finalize_global(obj: *mut JSObject) {
22 unsafe {
23 let protolist = get_proto_or_iface_array(obj);
24 let list = (*protolist).as_mut_ptr();
25 for idx in 0..PROTO_OR_IFACE_LENGTH as isize {
26 let entry = list.offset(idx);
27 let value = *entry;
28 <*mut JSObject>::post_barrier(entry, value, ptr::null_mut());
29 }
30 let _: Box<ProtoOrIfaceArray> = Box::from_raw(protolist);
31 }
32}
33
34pub(crate) unsafe fn finalize_common<T: DomObject>(this: *const T) {
37 if !this.is_null() {
38 let this = unsafe { Box::from_raw(this as *mut T) };
40 this.reflector().drop_memory(&*this);
41 }
42 debug!("{} finalize: {:p}", type_name::<T>(), this);
43}
44
45pub(crate) unsafe fn finalize_global<T: DomObject>(obj: *mut JSObject, this: *const T) {
49 unsafe {
50 do_finalize_global(obj);
51 finalize_common::<T>(this);
52 }
53}
54
55pub(crate) unsafe fn finalize_weak_referenceable<T: WeakReferenceable>(
59 obj: *mut JSObject,
60 this: *const T,
61) {
62 let mut slot = UndefinedValue();
63 unsafe { JS_GetReservedSlot(obj, DOM_WEAK_SLOT, &mut slot) };
64 let weak_box_ptr = slot.to_private() as *mut WeakBox<T>;
65 if !weak_box_ptr.is_null() {
66 let count = {
67 let weak_box = unsafe { &*weak_box_ptr };
68 assert!(weak_box.value.get().is_some());
69 assert!(weak_box.count.get() > 0);
70 weak_box.value.set(None);
71 let count = weak_box.count.get() - 1;
72 weak_box.count.set(count);
73 count
74 };
75 if count == 0 {
76 mem::drop(unsafe { Box::from_raw(weak_box_ptr) });
77 }
78 }
79 unsafe { finalize_common::<T>(this) };
80}