script/dom/performance/
performancemark.rs1use js::gc::HandleValue;
6use js::jsapi::Heap;
7use js::jsval::{JSVal, NullValue};
8use js::rust::{HandleObject, MutableHandleValue};
9use script_bindings::codegen::GenericBindings::PerformanceBinding::PerformanceMarkOptions;
10
11use crate::dom::PERFORMANCE_TIMING_ATTRIBUTES;
12use crate::dom::bindings::codegen::Bindings::PerformanceMarkBinding::PerformanceMarkMethods;
13use crate::dom::bindings::error::{Error, Fallible};
14use crate::dom::bindings::inheritance::Castable;
15use crate::dom::bindings::structuredclone;
16use crate::dom::bindings::trace::RootedTraceableBox;
17use crate::dom::window::Window;
18use crate::script_runtime::JSContext;
19
20impl_performance_entry_struct!(
21 PerformanceMarkBinding,
22 PerformanceMark, EntryType::Mark,
23 {
24 #[ignore_malloc_size_of = "Defined in rust-mozjs"]
25 detail: Heap<JSVal>,
26 }
27);
28
29impl PerformanceMark {
30 fn set_detail(&self, handle: HandleValue<'_>) {
31 self.detail.set(handle.get());
32 }
33
34 pub(crate) fn new_with_proto(
35 cx: &mut js::context::JSContext,
36 global: &GlobalScope,
37 _proto: Option<HandleObject>,
38 mark_name: DOMString,
39 mark_options: RootedTraceableBox<PerformanceMarkOptions>,
40 ) -> Fallible<DomRoot<PerformanceMark>> {
41 if global.is::<Window>() && PERFORMANCE_TIMING_ATTRIBUTES.contains(&&*mark_name.str()) {
45 return Err(Error::Syntax(Some(
46 "Read-only attribute cannot be used as a mark name".to_owned(),
47 )));
48 }
49
50 let start_time = match mark_options.startTime {
54 Some(start_time) => {
56 if start_time.is_sign_negative() {
58 return Err(Error::Type(c"startTime must not be negative".to_owned()));
59 }
60 global.performance().time_origin() +
62 Duration::microseconds(start_time.mul_add(1000.0, 0.0) as i64)
63 },
64 None => CrossProcessInstant::now(),
66 };
67
68 let entry = PerformanceMark::new(
70 global,
71 mark_name,
72 start_time,
73 Duration::ZERO,
74 Default::default(),
75 );
76
77 rooted!(&in(cx) let mut detail = NullValue());
79
80 if !mark_options.detail.get().is_null_or_undefined() {
82 let record = structuredclone::write(cx, mark_options.detail.handle(), None)?;
84
85 structuredclone::read(cx, global, record, detail.handle_mut())?;
87 }
88 entry.set_detail(detail.handle());
89
90 Ok(entry)
91 }
92}
93
94impl PerformanceMarkMethods<crate::DomTypeHolder> for PerformanceMark {
95 fn Detail(&self, _cx: JSContext, mut retval: MutableHandleValue) {
96 retval.set(self.detail.get())
97 }
98
99 fn Constructor(
101 cx: &mut js::context::JSContext,
102 global: &GlobalScope,
103 proto: Option<HandleObject>,
104 mark_name: DOMString,
105 mark_options: RootedTraceableBox<PerformanceMarkOptions>,
106 ) -> Fallible<DomRoot<PerformanceMark>> {
107 PerformanceMark::new_with_proto(cx, global, proto, mark_name, mark_options)
108 }
109}