Repository: servo/servo
File: components/script_bindings/settings_stack.rs (Rust)

Code before:
use js::rust::Runtime;

use crate::DomTypes;
use crate::interfaces::{DomHelpers, GlobalScopeHelpers};
use crate::root::{Dom, DomRoot};
use crate::script_runtime::CanGc;

#[derive(Debug, Eq, JSTraceable, PartialEq)]
pub enum StackEntryKind {
    Incumbent,
    Entry,
}

#[cfg_attr(crown, allow(crown::unrooted_must_root))]
#[derive(JSTraceable)]
pub struct StackEntry<D: DomTypes> {
    pub global: Dom<D::GlobalScope>,
    pub kind: StackEntryKind,
}

/// RAII struct that pushes and pops entries from the script settings stack.
pub struct GenericAutoEntryScript<D: DomTypes> {
    global: DomRoot<D::GlobalScope>,
    #[cfg(feature = "tracing")]
    #[allow(dead_code)]
    span: profile_traits::servo_tracing::span::EnteredSpan,
}

impl<D: DomTypes> GenericAutoEntryScript<D> {
    /// <https://html.spec.whatwg.org/multipage/#prepare-to-run-script>
    pub fn new(global: &D::GlobalScope) -> Self {
        let settings_stack = <D as DomHelpers<D>>::settings_stack();
        settings_stack.with(|stack| {
            trace!("Prepare to run script with {:p}", global);
            let mut stack = stack.borrow_mut();
            stack.push(StackEntry {
                global: Dom::from_ref(global),
                kind: StackEntryKind::Entry,
            });
            Self {
                global: DomRoot::from_ref(global),
                #[cfg(feature = "tracing")]
                span: profile_traits::info_span!(
                    "ScriptEvaluate",
                    url = global.get_url().to_string(),
                )
                .entered(),
            }
        })
    }
}

Review comment (suggestion):
I guess this is the part that is actually interesting. We could avoid the feature flag here, by exposing the `Span` type and friends in `profile_traits`. The actual implementation of the types could depend on additional feature flags (e.g. `tracing-rs` enables the tracing-rs backend, `hitrace` enables the hitrace backend, nothing enables the dummy backend as a fallback. Multiple feature enabled would result in a compile time error, or we decide on a priority) 

Code after:
use js::rust::Runtime;

use crate::DomTypes;
use crate::interfaces::{DomHelpers, GlobalScopeHelpers};
use crate::root::{Dom, DomRoot};
use crate::script_runtime::CanGc;

#[derive(Debug, Eq, JSTraceable, PartialEq)]
pub enum StackEntryKind {
    Incumbent,
    Entry,
}

#[cfg_attr(crown, allow(crown::unrooted_must_root))]
#[derive(JSTraceable)]
pub struct StackEntry<D: DomTypes> {
    pub global: Dom<D::GlobalScope>,
    pub kind: StackEntryKind,
}

/// RAII struct that pushes and pops entries from the script settings stack.
pub struct GenericAutoEntryScript<D: DomTypes> {
    global: DomRoot<D::GlobalScope>,
    #[cfg(feature = "tracing")]
    #[expect(dead_code)]
    span: tracing::span::EnteredSpan,
}

impl<D: DomTypes> GenericAutoEntryScript<D> {
    /// <https://html.spec.whatwg.org/multipage/#prepare-to-run-script>
    pub fn new(global: &D::GlobalScope) -> Self {
        let settings_stack = <D as DomHelpers<D>>::settings_stack();
        settings_stack.with(|stack| {
            trace!("Prepare to run script with {:p}", global);
            let mut stack = stack.borrow_mut();
            stack.push(StackEntry {
                global: Dom::from_ref(global),
                kind: StackEntryKind::Entry,
            });
            Self {
                global: DomRoot::from_ref(global),
                #[cfg(feature = "tracing")]
                span: tracing::info_span!(
                    "ScriptEvaluate",
                    servo_profiling = true,
                    url = global.get_url().to_string(),
                )
                .entered(),
            }
        })
    }