/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

//! The script runtime contains common traits and structs commonly used by the
//! script thread, the dom, and the worker threads.

#![allow(dead_code)]

use core::ffi::c_char;
use std::cell::Cell;
use std::ffi::{CStr, CString};
use std::io::{Write, stdout};
use std::ops::Deref;
use std::os::raw::c_void;
use std::rc::Rc;
use std::sync::Mutex;
use std::time::{Duration, Instant};
use std::{os, ptr, thread};

use background_hang_monitor_api::ScriptHangAnnotation;
use js::conversions::jsstr_to_string;
use js::glue::{
    CollectServoSizes, CreateJobQueue, DeleteJobQueue, DispatchablePointer, DispatchableRun,
    JS_GetReservedSlot, JobQueueTraps, RUST_js_GetErrorMessage, SetBuildId, SetUpEventLoopDispatch,
    StreamConsumerConsumeChunk, StreamConsumerNoteResponseURLs, StreamConsumerStreamEnd,
    StreamConsumerStreamError,
};
use js::jsapi::{
    AsmJSOption, BuildIdCharVector, CompilationType, ContextOptionsRef,
    Dispatchable_MaybeShuttingDown, GCDescription, GCOptions, GCProgress, GCReason,
    GetPromiseUserInputEventHandlingState, HandleObject, HandleString,
    HandleValue as RawHandleValue, Heap, InitConsumeStreamCallback, JS_AddExtraGCRootsTracer,
    JS_InitDestroyPrincipalsCallback, JS_InitReadPrincipalsCallback, JS_NewObject,
    JS_NewStringCopyN, JS_SetGCCallback, JS_SetGCParameter, JS_SetGlobalJitCompilerOption,
    JS_SetOffthreadIonCompilationEnabled, JS_SetReservedSlot, JS_SetSecurityCallbacks,
    JSCLASS_RESERVED_SLOTS_MASK, JSCLASS_RESERVED_SLOTS_SHIFT, JSClass, JSClassOps,
    JSContext as RawJSContext, JSGCParamKey, JSGCStatus, JSJitCompilerOption, JSObject,
    JSSecurityCallbacks, JSTracer, JobQueue, MimeType, MutableHandleObject, MutableHandleString,
    PromiseRejectionHandlingState, PromiseUserInputEventHandlingState, RuntimeCode,
    SetDOMCallbacks, SetGCSliceCallback, SetJobQueue, SetPreserveWrapperCallbacks,
    SetProcessBuildIdOp, SetPromiseRejectionTrackerCallback, StreamConsumer as JSStreamConsumer,
};
use js::jsval::{ObjectValue, UndefinedValue};
use js::panic::wrap_panic;
pub(crate) use js::rust::ThreadSafeJSContext;
use js::rust::wrappers::{GetPromiseIsHandled, JS_GetPromiseResult};
use js::rust::{
    Handle, HandleObject as RustHandleObject, HandleValue, IntoHandle, JSEngine, JSEngineHandle,
    ParentRuntime, Runtime as RustRuntime,
};
use malloc_size_of::MallocSizeOfOps;
use malloc_size_of_derive::MallocSizeOf;
use profile_traits::mem::{Report, ReportKind};
use profile_traits::path;
use profile_traits::time::ProfilerCategory;
use script_bindings::script_runtime::{mark_runtime_dead, runtime_is_alive};
use servo_config::{opts, pref};
use style::thread_state::{self, ThreadState};

use crate::body::BodyMixin;
use crate::dom::bindings::codegen::Bindings::PromiseBinding::PromiseJobCallback;
use crate::dom::bindings::codegen::Bindings::ResponseBinding::Response_Binding::ResponseMethods;
use crate::dom::bindings::codegen::Bindings::ResponseBinding::ResponseType as DOMResponseType;
use crate::dom::bindings::conversions::{
    get_dom_class, private_from_object, root_from_handleobject, root_from_object,
};
use crate::dom::bindings::error::{Error, throw_dom_exception};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::{
    LiveDOMReferences, Trusted, TrustedPromise, trace_refcounted_objects,
};
use crate::dom::bindings::reflector::{DomGlobal, DomObject};
use crate::dom::bindings::root::trace_roots;
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::utils::DOM_CALLBACKS;
use crate::dom::bindings::{principals, settings_stack};
use crate::dom::csp::CspReporting;
use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise;
use crate::dom::promiserejectionevent::PromiseRejectionEvent;
use crate::dom::response::Response;
use crate::dom::trustedscript::TrustedScript;
use crate::microtask::{EnqueuedPromiseCallback, Microtask, MicrotaskQueue};
use crate::realms::{AlreadyInRealm, InRealm, enter_realm};
use crate::script_module::EnsureModuleHooksInitialized;
use crate::script_thread::trace_thread;
use crate::task_source::SendableTaskSource;

static JOB_QUEUE_TRAPS: JobQueueTraps = JobQueueTraps {
    getHostDefinedData: Some(get_host_defined_data),
    enqueuePromiseJob: Some(enqueue_promise_job),
    runJobs: Some(run_jobs),
    empty: Some(empty),
    pushNewInterruptQueue: Some(push_new_interrupt_queue),
    popInterruptQueue: Some(pop_interrupt_queue),
    dropInterruptQueues: Some(drop_interrupt_queues),
};

static SECURITY_CALLBACKS: JSSecurityCallbacks = JSSecurityCallbacks {
    contentSecurityPolicyAllows: Some(content_security_policy_allows),
    codeForEvalGets: Some(code_for_eval_gets),
    subsumes: Some(principals::subsumes),
};

#[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, MallocSizeOf, PartialEq)]
pub(crate) enum ScriptThreadEventCategory {
    AttachLayout,
    ConstellationMsg,
    DatabaseAccessEvent,
    DevtoolsMsg,
    DocumentEvent,
    FileRead,
    FontLoading,
    FormPlannedNavigation,
    HistoryEvent,
    ImageCacheMsg,
    InputEvent,
    NetworkEvent,
    PortMessage,
    Rendering,
    Resize,
    ScriptEvent,
    SetScrollState,
    SetViewport,
    StylesheetLoad,
    TimerEvent,
    UpdateReplacedElement,
    WebSocketEvent,
    WorkerEvent,
    WorkletEvent,
    ServiceWorkerEvent,
    EnterFullscreen,
    ExitFullscreen,
    PerformanceTimelineTask,
    #[cfg(feature = "webgpu")]
    WebGPUMsg,
}

impl From<ScriptThreadEventCategory> for ProfilerCategory {
    fn from(category: ScriptThreadEventCategory) -> Self {
        match category {
            ScriptThreadEventCategory::AttachLayout => ProfilerCategory::ScriptAttachLayout,
            ScriptThreadEventCategory::ConstellationMsg => ProfilerCategory::ScriptConstellationMsg,
            ScriptThreadEventCategory::DatabaseAccessEvent => {
                ProfilerCategory::ScriptDatabaseAccessEvent
            },
            ScriptThreadEventCategory::DevtoolsMsg => ProfilerCategory::ScriptDevtoolsMsg,
            ScriptThreadEventCategory::DocumentEvent => ProfilerCategory::ScriptDocumentEvent,
            ScriptThreadEventCategory::EnterFullscreen => ProfilerCategory::ScriptEnterFullscreen,
            ScriptThreadEventCategory::ExitFullscreen => ProfilerCategory::ScriptExitFullscreen,
            ScriptThreadEventCategory::FileRead => ProfilerCategory::ScriptFileRead,
            ScriptThreadEventCategory::FontLoading => ProfilerCategory::ScriptFontLoading,
            ScriptThreadEventCategory::FormPlannedNavigation => {
                ProfilerCategory::ScriptPlannedNavigation
            },
            ScriptThreadEventCategory::HistoryEvent => ProfilerCategory::ScriptHistoryEvent,
            ScriptThreadEventCategory::ImageCacheMsg => ProfilerCategory::ScriptImageCacheMsg,
            ScriptThreadEventCategory::InputEvent => ProfilerCategory::ScriptInputEvent,
            ScriptThreadEventCategory::NetworkEvent => ProfilerCategory::ScriptNetworkEvent,
            ScriptThreadEventCategory::PerformanceTimelineTask => {
                ProfilerCategory::ScriptPerformanceEvent
            },
            ScriptThreadEventCategory::PortMessage => ProfilerCategory::ScriptPortMessage,
            ScriptThreadEventCategory::Resize => ProfilerCategory::ScriptResize,
            ScriptThreadEventCategory::Rendering => ProfilerCategory::ScriptRendering,
            ScriptThreadEventCategory::ScriptEvent => ProfilerCategory::ScriptEvent,
            ScriptThreadEventCategory::ServiceWorkerEvent => {
                ProfilerCategory::ScriptServiceWorkerEvent
            },
            ScriptThreadEventCategory::SetScrollState => ProfilerCategory::ScriptSetScrollState,
            ScriptThreadEventCategory::SetViewport => ProfilerCategory::ScriptSetViewport,
            ScriptThreadEventCategory::StylesheetLoad => ProfilerCategory::ScriptStylesheetLoad,
            ScriptThreadEventCategory::TimerEvent => ProfilerCategory::ScriptTimerEvent,
            ScriptThreadEventCategory::UpdateReplacedElement => {
                ProfilerCategory::ScriptUpdateReplacedElement
            },
            ScriptThreadEventCategory::WebSocketEvent => ProfilerCategory::ScriptWebSocketEvent,
            ScriptThreadEventCategory::WorkerEvent => ProfilerCategory::ScriptWorkerEvent,
            ScriptThreadEventCategory::WorkletEvent => ProfilerCategory::ScriptWorkletEvent,
            #[cfg(feature = "webgpu")]
            ScriptThreadEventCategory::WebGPUMsg => ProfilerCategory::ScriptWebGPUMsg,
        }
    }
}

impl From<ScriptThreadEventCategory> for ScriptHangAnnotation {
    fn from(category: ScriptThreadEventCategory) -> Self {
        match category {
            ScriptThreadEventCategory::AttachLayout => ScriptHangAnnotation::AttachLayout,
            ScriptThreadEventCategory::ConstellationMsg => ScriptHangAnnotation::ConstellationMsg,
            ScriptThreadEventCategory::DatabaseAccessEvent => {
                ScriptHangAnnotation::DatabaseAccessEvent
            },
            ScriptThreadEventCategory::DevtoolsMsg => ScriptHangAnnotation::DevtoolsMsg,
            ScriptThreadEventCategory::DocumentEvent => ScriptHangAnnotation::DocumentEvent,
            ScriptThreadEventCategory::InputEvent => ScriptHangAnnotation::InputEvent,
            ScriptThreadEventCategory::FileRead => ScriptHangAnnotation::FileRead,
            ScriptThreadEventCategory::FontLoading => ScriptHangAnnotation::FontLoading,
            ScriptThreadEventCategory::FormPlannedNavigation => {
                ScriptHangAnnotation::FormPlannedNavigation
            },
            ScriptThreadEventCategory::HistoryEvent => ScriptHangAnnotation::HistoryEvent,
            ScriptThreadEventCategory::ImageCacheMsg => ScriptHangAnnotation::ImageCacheMsg,
            ScriptThreadEventCategory::NetworkEvent => ScriptHangAnnotation::NetworkEvent,
            ScriptThreadEventCategory::Rendering => ScriptHangAnnotation::Rendering,
            ScriptThreadEventCategory::Resize => ScriptHangAnnotation::Resize,
            ScriptThreadEventCategory::ScriptEvent => ScriptHangAnnotation::ScriptEvent,
            ScriptThreadEventCategory::SetScrollState => ScriptHangAnnotation::SetScrollState,
            ScriptThreadEventCategory::SetViewport => ScriptHangAnnotation::SetViewport,
            ScriptThreadEventCategory::StylesheetLoad => ScriptHangAnnotation::StylesheetLoad,
            ScriptThreadEventCategory::TimerEvent => ScriptHangAnnotation::TimerEvent,
            ScriptThreadEventCategory::UpdateReplacedElement => {
                ScriptHangAnnotation::UpdateReplacedElement
            },
            ScriptThreadEventCategory::WebSocketEvent => ScriptHangAnnotation::WebSocketEvent,
            ScriptThreadEventCategory::WorkerEvent => ScriptHangAnnotation::WorkerEvent,
            ScriptThreadEventCategory::WorkletEvent => ScriptHangAnnotation::WorkletEvent,
            ScriptThreadEventCategory::ServiceWorkerEvent => {
                ScriptHangAnnotation::ServiceWorkerEvent
            },
            ScriptThreadEventCategory::EnterFullscreen => ScriptHangAnnotation::EnterFullscreen,
            ScriptThreadEventCategory::ExitFullscreen => ScriptHangAnnotation::ExitFullscreen,
            ScriptThreadEventCategory::PerformanceTimelineTask => {
                ScriptHangAnnotation::PerformanceTimelineTask
            },
            ScriptThreadEventCategory::PortMessage => ScriptHangAnnotation::PortMessage,
            #[cfg(feature = "webgpu")]
            ScriptThreadEventCategory::WebGPUMsg => ScriptHangAnnotation::WebGPUMsg,
        }
    }
}

static HOST_DEFINED_DATA: JSClassOps = JSClassOps {
    addProperty: None,
    delProperty: None,
    enumerate: None,
    newEnumerate: None,
    resolve: None,
    mayResolve: None,
    finalize: None,
    call: None,
    construct: None,
    trace: None,
};

static HOST_DEFINED_DATA_CLASS: JSClass = JSClass {
    name: c"HostDefinedData".as_ptr(),
    flags: (HOST_DEFINED_DATA_SLOTS & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT,
    cOps: &HOST_DEFINED_DATA,
    spec: ptr::null(),
    ext: ptr::null(),
    oOps: ptr::null(),
};

const INCUMBENT_SETTING_SLOT: u32 = 0;
const HOST_DEFINED_DATA_SLOTS: u32 = 1;

/// <https://searchfox.org/mozilla-central/rev/2a8a30f4c9b918b726891ab9d2d62b76152606f1/xpcom/base/CycleCollectedJSContext.cpp#316>
#[allow(unsafe_code)]
unsafe extern "C" fn get_host_defined_data(
    _: *const c_void,
    cx: *mut RawJSContext,
    data: MutableHandleObject,
) -> bool {
    wrap_panic(&mut || {
        let Some(incumbent_global) = GlobalScope::incumbent() else {
            data.set(ptr::null_mut());
            return;
        };

        let _realm = enter_realm(&*incumbent_global);

        rooted!(in(cx) let result = JS_NewObject(cx, &HOST_DEFINED_DATA_CLASS));
        assert!(!result.is_null());

        JS_SetReservedSlot(
            *result,
            INCUMBENT_SETTING_SLOT,
            &ObjectValue(*incumbent_global.reflector().get_jsobject()),
        );

        data.set(result.get());
    });
    true
}

#[allow(unsafe_code)]
unsafe extern "C" fn run_jobs(microtask_queue: *const c_void, cx: *mut RawJSContext) {
    let cx = JSContext::from_ptr(cx);
    wrap_panic(&mut || {
        let microtask_queue = &*(microtask_queue as *const MicrotaskQueue);
        // TODO: run Promise- and User-variant Microtasks, and do #notify-about-rejected-promises.
        // Those will require real `target_provider` and `globalscopes` values.
        microtask_queue.checkpoint(cx, |_| None, vec![], CanGc::note());
    });
}

#[allow(unsafe_code)]
unsafe extern "C" fn empty(extra: *const c_void) -> bool {
    let mut result = false;
    wrap_panic(&mut || {
        let microtask_queue = &*(extra as *const MicrotaskQueue);
        result = microtask_queue.empty()
    });
    result
}

#[allow(unsafe_code)]
unsafe extern "C" fn push_new_interrupt_queue(interrupt_queues: *mut c_void) -> *const c_void {
    let mut result = std::ptr::null();
    wrap_panic(&mut || {
        let mut interrupt_queues = Box::from_raw(interrupt_queues as *mut Vec<Rc<MicrotaskQueue>>);
        let new_queue = Rc::new(MicrotaskQueue::default());
        result = Rc::as_ptr(&new_queue) as *const c_void;
        interrupt_queues.push(new_queue.clone());
        std::mem::forget(interrupt_queues);
    });
    result
}

#[allow(unsafe_code)]
unsafe extern "C" fn pop_interrupt_queue(interrupt_queues: *mut c_void) -> *const c_void {
    let mut result = std::ptr::null();
    wrap_panic(&mut || {
        let mut interrupt_queues = Box::from_raw(interrupt_queues as *mut Vec<Rc<MicrotaskQueue>>);
        let popped_queue: Rc<MicrotaskQueue> =
            interrupt_queues.pop().expect("Guaranteed by SpiderMonkey?");
        // Dangling, but jsglue.cpp will only use this for pointer comparison.
        result = Rc::as_ptr(&popped_queue) as *const c_void;
        std::mem::forget(interrupt_queues);
    });
    result
}

#[allow(unsafe_code)]
unsafe extern "C" fn drop_interrupt_queues(interrupt_queues: *mut c_void) {
    wrap_panic(&mut || {
        let interrupt_queues = Box::from_raw(interrupt_queues as *mut Vec<Rc<MicrotaskQueue>>);
        drop(interrupt_queues);
    });
}

/// <https://searchfox.org/mozilla-central/rev/2a8a30f4c9b918b726891ab9d2d62b76152606f1/xpcom/base/CycleCollectedJSContext.cpp#355>
/// SM callback for promise job resolution. Adds a promise callback to the current
/// global's microtask queue.
#[allow(unsafe_code)]
unsafe extern "C" fn enqueue_promise_job(
    extra: *const c_void,
    cx: *mut RawJSContext,
    promise: HandleObject,
    job: HandleObject,
    _allocation_site: HandleObject,
    host_defined_data: HandleObject,
) -> bool {
    let cx = JSContext::from_ptr(cx);
    let mut result = false;
    wrap_panic(&mut || {
        let microtask_queue = &*(extra as *const MicrotaskQueue);
        let global = if !host_defined_data.is_null() {
            let mut incumbent_global = UndefinedValue();
            JS_GetReservedSlot(
                host_defined_data.get(),
                INCUMBENT_SETTING_SLOT,
                &mut incumbent_global,
            );
            GlobalScope::from_object(incumbent_global.to_object())
        } else {
            let realm = AlreadyInRealm::assert_for_cx(cx);
            GlobalScope::from_context(*cx, InRealm::already(&realm))
        };
        let pipeline = global.pipeline_id();
        let interaction = if promise.get().is_null() {
            PromiseUserInputEventHandlingState::DontCare
        } else {
            GetPromiseUserInputEventHandlingState(promise)
        };
        let is_user_interacting =
            interaction == PromiseUserInputEventHandlingState::HadUserInteractionAtCreation;
        microtask_queue.enqueue(
            Microtask::Promise(EnqueuedPromiseCallback {
                callback: PromiseJobCallback::new(cx, job.get()),
                pipeline,
                is_user_interacting,
            }),
            cx,
        );
        result = true
    });
    result
}

#[allow(unsafe_code)]
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
/// <https://html.spec.whatwg.org/multipage/#the-hostpromiserejectiontracker-implementation>
unsafe extern "C" fn promise_rejection_tracker(
    cx: *mut RawJSContext,
    _muted_errors: bool,
    promise: HandleObject,
    state: PromiseRejectionHandlingState,
    _data: *mut c_void,
) {
    // TODO: Step 2 - If script's muted errors is true, terminate these steps.

    // Step 3.
    let cx = JSContext::from_ptr(cx);
    let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
    let global = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));

    wrap_panic(&mut || {
        match state {
            // Step 4.
            PromiseRejectionHandlingState::Unhandled => {
                global.add_uncaught_rejection(promise);
            },
            // Step 5.
            PromiseRejectionHandlingState::Handled => {
                // Step 5-1.
                if global
                    .get_uncaught_rejections()
                    .borrow()
                    .contains(&Heap::boxed(promise.get()))
                {
                    global.remove_uncaught_rejection(promise);
                    return;
                }

                // Step 5-2.
                if !global
                    .get_consumed_rejections()
                    .borrow()
                    .contains(&Heap::boxed(promise.get()))
                {
                    return;
                }

                // Step 5-3.
                global.remove_consumed_rejection(promise);

                let target = Trusted::new(global.upcast::<EventTarget>());
                let promise = Promise::new_with_js_promise(Handle::from_raw(promise), cx);
                let trusted_promise = TrustedPromise::new(promise.clone());

                // Step 5-4.
                global.task_manager().dom_manipulation_task_source().queue(
                task!(rejection_handled_event: move || {
                    let target = target.root();
                    let cx = GlobalScope::get_cx();
                    let root_promise = trusted_promise.root();

                    rooted!(in(*cx) let mut reason = UndefinedValue());
                    JS_GetPromiseResult(root_promise.reflector().get_jsobject(), reason.handle_mut());

                    let event = PromiseRejectionEvent::new(
                        &target.global(),
                        atom!("rejectionhandled"),
                        EventBubbles::DoesNotBubble,
                        EventCancelable::Cancelable,
                        root_promise,
                        reason.handle(),
                        CanGc::note()
                    );

                    event.upcast::<Event>().fire(&target, CanGc::note());
                })
            );
            },
        };
    })
}

#[allow(unsafe_code)]
fn safely_convert_null_to_string(cx: JSContext, str_: HandleString) -> DOMString {
    DOMString::from(match std::ptr::NonNull::new(*str_) {
        None => "".to_owned(),
        Some(str_) => unsafe { jsstr_to_string(*cx, str_) },
    })
}

#[allow(unsafe_code)]
unsafe extern "C" fn code_for_eval_gets(
    cx: *mut RawJSContext,
    code: HandleObject,
    code_for_eval: MutableHandleString,
) -> bool {
    let cx = JSContext::from_ptr(cx);
    if let Ok(trusted_script) = root_from_object::<TrustedScript>(code.get(), *cx) {
        let script_string = trusted_script.data();
        let new_string = JS_NewStringCopyN(
            *cx,
            script_string.as_ptr() as *const libc::c_char,
            script_string.len(),
        );
        code_for_eval.set(new_string);
    }
    true
}

#[allow(unsafe_code)]
unsafe extern "C" fn content_security_policy_allows(
    cx: *mut RawJSContext,
    runtime_code: RuntimeCode,
    code_string: HandleString,
    compilation_type: CompilationType,
    parameter_strings: u8, // FIXME in bindings generation
    body_string: HandleString,
    parameter_args: u8, // FIXME in bindings generation
    body_arg: RawHandleValue,
    can_compile_strings: *mut bool,
) -> bool {
    let mut allowed = false;
    let cx = JSContext::from_ptr(cx);
    wrap_panic(&mut || {
        // SpiderMonkey provides null pointer when executing webassembly.
        let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
        let global = &GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));

        allowed = match runtime_code {
            RuntimeCode::JS => TrustedScript::can_compile_string_with_trusted_type(
                cx,
                global,
                safely_convert_null_to_string(cx, code_string),
                compilation_type,
                parameter_strings,
                safely_convert_null_to_string(cx, body_string),
                parameter_args,
                HandleValue::from_raw(body_arg),
                CanGc::note(),
            ),
            RuntimeCode::WASM => global.get_csp_list().is_wasm_evaluation_allowed(global),
        };
    });
    *can_compile_strings = allowed;
    true
}

#[allow(unsafe_code)]
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
/// <https://html.spec.whatwg.org/multipage/#notify-about-rejected-promises>
pub(crate) fn notify_about_rejected_promises(global: &GlobalScope) {
    let cx = GlobalScope::get_cx();
    unsafe {
        // Step 2.
        if !global.get_uncaught_rejections().borrow().is_empty() {
            // Step 1.
            let uncaught_rejections: Vec<TrustedPromise> = global
                .get_uncaught_rejections()
                .borrow()
                .iter()
                .map(|promise| {
                    let promise =
                        Promise::new_with_js_promise(Handle::from_raw(promise.handle()), cx);

                    TrustedPromise::new(promise)
                })
                .collect();

            // Step 3.
            global.get_uncaught_rejections().borrow_mut().clear();

            let target = Trusted::new(global.upcast::<EventTarget>());

            // Step 4.
            global.task_manager().dom_manipulation_task_source().queue(
                task!(unhandled_rejection_event: move || {
                    let target = target.root();
                    let cx = GlobalScope::get_cx();

                    for promise in uncaught_rejections {
                        let promise = promise.root();

                        // Step 4-1.
                        let promise_is_handled = GetPromiseIsHandled(promise.reflector().get_jsobject());
                        if promise_is_handled {
                            continue;
                        }

                        // Step 4-2.
                        rooted!(in(*cx) let mut reason = UndefinedValue());
                        JS_GetPromiseResult(promise.reflector().get_jsobject(), reason.handle_mut());

                        let event = PromiseRejectionEvent::new(
                            &target.global(),
                            atom!("unhandledrejection"),
                            EventBubbles::DoesNotBubble,
                            EventCancelable::Cancelable,
                            promise.clone(),
                            reason.handle(),
                            CanGc::note()
                        );

                        let not_canceled = event.upcast::<Event>().fire(&target, CanGc::note());

                        // Step 4-3. If notCanceled is true, then the user agent
                        // may report p.[[PromiseResult]] to a developer console.
                        if not_canceled {
                            // TODO: The promise rejection is not handled; we need to add it back to the list.
                        }

                        // Step 4-4.
                        if !promise_is_handled {
                            target.global().add_consumed_rejection(promise.reflector().get_jsobject().into_handle());
                        }
                    }
                })
            );
        }
    }
}

#[derive(JSTraceable)]
pub(crate) struct Runtime {
    rt: RustRuntime,
    /// Our actual microtask queue, which is preserved and untouched by the debugger when running debugger scripts.
    pub(crate) microtask_queue: Rc<MicrotaskQueue>,
    job_queue: *mut JobQueue,
    networking_task_src: Option<Box<SendableTaskSource>>,
}

impl Runtime {
    /// Create a new runtime, optionally with the given [`SendableTaskSource`] for networking.
    ///
    /// # Safety
    ///
    /// If panicking does not abort the program, any threads with child runtimes will continue
    /// executing after the thread with the parent runtime panics, but they will be in an
    /// invalid and undefined state.
    ///
    /// This, like many calls to SpiderMoney API, is unsafe.
    #[allow(unsafe_code)]
    pub(crate) fn new(networking_task_source: Option<SendableTaskSource>) -> Runtime {
        unsafe { Self::new_with_parent(None, networking_task_source) }
    }

    /// Create a new runtime, optionally with the given [`ParentRuntime`] and [`SendableTaskSource`]
    /// for networking.
    ///
    /// # Safety
    ///
    /// If panicking does not abort the program, any threads with child runtimes will continue
    /// executing after the thread with the parent runtime panics, but they will be in an
    /// invalid and undefined state.
    ///
    /// The `parent` pointer in the [`ParentRuntime`] argument must point to a valid object in memory.
    ///
    /// This, like many calls to the SpiderMoney API, is unsafe.
    #[allow(unsafe_code)]
    pub(crate) unsafe fn new_with_parent(
        parent: Option<ParentRuntime>,
        networking_task_source: Option<SendableTaskSource>,
    ) -> Runtime {
        let (cx, runtime) = if let Some(parent) = parent {
            let runtime = RustRuntime::create_with_parent(parent);
            let cx = runtime.cx();
            (cx, runtime)
        } else {
            let runtime = RustRuntime::new(JS_ENGINE.lock().unwrap().as_ref().unwrap().clone());
            (runtime.cx(), runtime)
        };

        JS_AddExtraGCRootsTracer(cx, Some(trace_rust_roots), ptr::null_mut());

        JS_SetSecurityCallbacks(cx, &SECURITY_CALLBACKS);

        JS_InitDestroyPrincipalsCallback(cx, Some(principals::destroy_servo_jsprincipal));
        JS_InitReadPrincipalsCallback(cx, Some(principals::read_jsprincipal));

        // Needed for debug assertions about whether GC is running.
        if cfg!(debug_assertions) {
            JS_SetGCCallback(cx, Some(debug_gc_callback), ptr::null_mut());
        }

        if opts::get().debug.gc_profile {
            SetGCSliceCallback(cx, Some(gc_slice_callback));
        }

        unsafe extern "C" fn empty_wrapper_callback(_: *mut RawJSContext, _: HandleObject) -> bool {
            true
        }
        unsafe extern "C" fn empty_has_released_callback(_: HandleObject) -> bool {
            // fixme: return true when the Drop impl for a DOM object has been invoked
            false
        }
        SetDOMCallbacks(cx, &DOM_CALLBACKS);
        SetPreserveWrapperCallbacks(
            cx,
            Some(empty_wrapper_callback),
            Some(empty_has_released_callback),
        );
        // Pre barriers aren't working correctly at the moment
        JS_SetGCParameter(cx, JSGCParamKey::JSGC_INCREMENTAL_GC_ENABLED, 0);

        unsafe extern "C" fn dispatch_to_event_loop(
            closure: *mut c_void,
            dispatchable: *mut DispatchablePointer,
        ) -> bool {
            let networking_task_src: &SendableTaskSource = &*(closure as *mut SendableTaskSource);
            let runnable = Runnable(dispatchable);
            let task = task!(dispatch_to_event_loop_message: move || {
                if let Some(cx) = RustRuntime::get() {
                    runnable.run(cx.as_ptr(), Dispatchable_MaybeShuttingDown::NotShuttingDown);
                }
            });

            networking_task_src.queue_unconditionally(task);
            true
        }

        let mut networking_task_src_ptr = std::ptr::null_mut();
        if let Some(source) = networking_task_source {
            networking_task_src_ptr = Box::into_raw(Box::new(source));
            SetUpEventLoopDispatch(
                cx,
                Some(dispatch_to_event_loop),
                networking_task_src_ptr as *mut c_void,
            );
        }

        InitConsumeStreamCallback(cx, Some(consume_stream), Some(report_stream_error));

        let microtask_queue = Rc::new(MicrotaskQueue::default());

        // Extra queues for debugger scripts (“interrupts”) via AutoDebuggerJobQueueInterruption and saveJobQueue().
        // Moved indefinitely to mozjs via CreateJobQueue(), borrowed from mozjs via JobQueueTraps, and moved back from
        // mozjs for dropping via DeleteJobQueue().
        let interrupt_queues: Box<Vec<Rc<MicrotaskQueue>>> = Box::default();

        let job_queue = CreateJobQueue(
            &JOB_QUEUE_TRAPS,
            &*microtask_queue as *const _ as *const c_void,
            Box::into_raw(interrupt_queues) as *mut c_void,
        );
        SetJobQueue(cx, job_queue);
        SetPromiseRejectionTrackerCallback(cx, Some(promise_rejection_tracker), ptr::null_mut());

        EnsureModuleHooksInitialized(runtime.rt());

        set_gc_zeal_options(cx);

        // Enable or disable the JITs.
        let cx_opts = &mut *ContextOptionsRef(cx);
        JS_SetGlobalJitCompilerOption(
            cx,
            JSJitCompilerOption::JSJITCOMPILER_BASELINE_INTERPRETER_ENABLE,
            pref!(js_baseline_interpreter_enabled) as u32,
        );
        JS_SetGlobalJitCompilerOption(
            cx,
            JSJitCompilerOption::JSJITCOMPILER_BASELINE_ENABLE,
            pref!(js_baseline_jit_enabled) as u32,
        );
        JS_SetGlobalJitCompilerOption(
            cx,
            JSJitCompilerOption::JSJITCOMPILER_ION_ENABLE,
            pref!(js_ion_enabled) as u32,
        );
        cx_opts.compileOptions_.asmJSOption_ = if pref!(js_asmjs_enabled) {
            AsmJSOption::Enabled
        } else {
            AsmJSOption::DisabledByAsmJSPref
        };
        let wasm_enabled = pref!(js_wasm_enabled);
        cx_opts.set_wasm_(wasm_enabled);
        if wasm_enabled {
            // If WASM is enabled without setting the buildIdOp,
            // initializing a module will report an out of memory error.
            // https://dxr.mozilla.org/mozilla-central/source/js/src/wasm/WasmTypes.cpp#458
            SetProcessBuildIdOp(Some(servo_build_id));
        }
        cx_opts.set_wasmBaseline_(pref!(js_wasm_baseline_enabled));
        cx_opts.set_wasmIon_(pref!(js_wasm_ion_enabled));
        // TODO: handle js.throw_on_asmjs_validation_failure (needs new Spidermonkey)
        JS_SetGlobalJitCompilerOption(
            cx,
            JSJitCompilerOption::JSJITCOMPILER_NATIVE_REGEXP_ENABLE,
            pref!(js_native_regex_enabled) as u32,
        );
        JS_SetOffthreadIonCompilationEnabled(cx, pref!(js_offthread_compilation_enabled));
        JS_SetGlobalJitCompilerOption(
            cx,
            JSJitCompilerOption::JSJITCOMPILER_BASELINE_WARMUP_TRIGGER,
            if pref!(js_baseline_jit_unsafe_eager_compilation_enabled) {
                0
            } else {
                u32::MAX
            },
        );
        JS_SetGlobalJitCompilerOption(
            cx,
            JSJitCompilerOption::JSJITCOMPILER_ION_NORMAL_WARMUP_TRIGGER,
            if pref!(js_ion_unsafe_eager_compilation_enabled) {
                0
            } else {
                u32::MAX
            },
        );
        // TODO: handle js.discard_system_source.enabled
        // TODO: handle js.asyncstack.enabled (needs new Spidermonkey)
        // TODO: handle js.throw_on_debugee_would_run (needs new Spidermonkey)
        // TODO: handle js.dump_stack_on_debugee_would_run (needs new Spidermonkey)
        // TODO: handle js.shared_memory.enabled
        JS_SetGCParameter(
            cx,
            JSGCParamKey::JSGC_MAX_BYTES,
            in_range(pref!(js_mem_max), 1, 0x100)
                .map(|val| (val * 1024 * 1024) as u32)
                .unwrap_or(u32::MAX),
        );
        // NOTE: This is disabled above, so enabling it here will do nothing for now.
        JS_SetGCParameter(
            cx,
            JSGCParamKey::JSGC_INCREMENTAL_GC_ENABLED,
            pref!(js_mem_gc_incremental_enabled) as u32,
        );
        JS_SetGCParameter(
            cx,
            JSGCParamKey::JSGC_PER_ZONE_GC_ENABLED,
            pref!(js_mem_gc_per_zone_enabled) as u32,
        );
        if let Some(val) = in_range(pref!(js_mem_gc_incremental_slice_ms), 0, 100_000) {
            JS_SetGCParameter(cx, JSGCParamKey::JSGC_SLICE_TIME_BUDGET_MS, val as u32);
        }
        JS_SetGCParameter(
            cx,
            JSGCParamKey::JSGC_COMPACTING_ENABLED,
            pref!(js_mem_gc_compacting_enabled) as u32,
        );

        if let Some(val) = in_range(pref!(js_mem_gc_high_frequency_time_limit_ms), 0, 10_000) {
            JS_SetGCParameter(cx, JSGCParamKey::JSGC_HIGH_FREQUENCY_TIME_LIMIT, val as u32);
        }
        if let Some(val) = in_range(pref!(js_mem_gc_low_frequency_heap_growth), 0, 10_000) {
            JS_SetGCParameter(cx, JSGCParamKey::JSGC_LOW_FREQUENCY_HEAP_GROWTH, val as u32);
        }
        if let Some(val) = in_range(pref!(js_mem_gc_high_frequency_heap_growth_min), 0, 10_000) {
            JS_SetGCParameter(
                cx,
                JSGCParamKey::JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH,
                val as u32,
            );
        }
        if let Some(val) = in_range(pref!(js_mem_gc_high_frequency_heap_growth_max), 0, 10_000) {
            JS_SetGCParameter(
                cx,
                JSGCParamKey::JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH,
                val as u32,
            );
        }
        if let Some(val) = in_range(pref!(js_mem_gc_high_frequency_low_limit_mb), 0, 10_000) {
            JS_SetGCParameter(cx, JSGCParamKey::JSGC_SMALL_HEAP_SIZE_MAX, val as u32);
        }
        if let Some(val) = in_range(pref!(js_mem_gc_high_frequency_high_limit_mb), 0, 10_000) {
            JS_SetGCParameter(cx, JSGCParamKey::JSGC_LARGE_HEAP_SIZE_MIN, val as u32);
        }
        /*if let Some(val) = in_range(pref!(js_mem_gc_allocation_threshold_factor), 0, 10_000) {
            JS_SetGCParameter(cx, JSGCParamKey::JSGC_NON_INCREMENTAL_FACTOR, val as u32);
        }*/
        /*
            // JSGC_SMALL_HEAP_INCREMENTAL_LIMIT
            pref("javascript.options.mem.gc_small_heap_incremental_limit", 140);

            // JSGC_LARGE_HEAP_INCREMENTAL_LIMIT
            pref("javascript.options.mem.gc_large_heap_incremental_limit", 110);
        */
        if let Some(val) = in_range(pref!(js_mem_gc_empty_chunk_count_min), 0, 10_000) {
            JS_SetGCParameter(cx, JSGCParamKey::JSGC_MIN_EMPTY_CHUNK_COUNT, val as u32);
        }

        Runtime {
            rt: runtime,
            microtask_queue,
            job_queue,
            networking_task_src: (!networking_task_src_ptr.is_null())
                .then(|| Box::from_raw(networking_task_src_ptr)),
        }
    }

    pub(crate) fn thread_safe_js_context(&self) -> ThreadSafeJSContext {
        self.rt.thread_safe_js_context()
    }
}

impl Drop for Runtime {
    #[allow(unsafe_code)]
    fn drop(&mut self) {
        // Clear our main microtask_queue.
        self.microtask_queue.clear();

        // Delete the RustJobQueue in mozjs, which will destroy our interrupt queues.
        unsafe {
            DeleteJobQueue(self.job_queue);
        }
        LiveDOMReferences::destruct();
        mark_runtime_dead();
    }
}

impl Deref for Runtime {
    type Target = RustRuntime;
    fn deref(&self) -> &RustRuntime {
        &self.rt
    }
}

pub struct JSEngineSetup(JSEngine);

impl Default for JSEngineSetup {
    fn default() -> Self {
        let engine = JSEngine::init().unwrap();
        *JS_ENGINE.lock().unwrap() = Some(engine.handle());
        Self(engine)
    }
}

impl Drop for JSEngineSetup {
    fn drop(&mut self) {
        *JS_ENGINE.lock().unwrap() = None;

        while !self.0.can_shutdown() {
            thread::sleep(Duration::from_millis(50));
        }
    }
}

static JS_ENGINE: Mutex<Option<JSEngineHandle>> = Mutex::new(None);

fn in_range<T: PartialOrd + Copy>(val: T, min: T, max: T) -> Option<T> {
    if val < min || val >= max {
        None
    } else {
        Some(val)
    }
}

thread_local!(static MALLOC_SIZE_OF_OPS: Cell<*mut MallocSizeOfOps> = const { Cell::new(ptr::null_mut()) });

#[allow(unsafe_code)]
unsafe extern "C" fn get_size(obj: *mut JSObject) -> usize {
    match get_dom_class(obj) {
        Ok(v) => {
            let dom_object = private_from_object(obj) as *const c_void;

            if dom_object.is_null() {
                return 0;
            }
            let ops = MALLOC_SIZE_OF_OPS.get();
            (v.malloc_size_of)(&mut *ops, dom_object)
        },
        Err(_e) => 0,
    }
}

thread_local!(static GC_CYCLE_START: Cell<Option<Instant>> = const { Cell::new(None) });
thread_local!(static GC_SLICE_START: Cell<Option<Instant>> = const { Cell::new(None) });

#[allow(unsafe_code)]
unsafe extern "C" fn gc_slice_callback(
    _cx: *mut RawJSContext,
    progress: GCProgress,
    desc: *const GCDescription,
) {
    match progress {
        GCProgress::GC_CYCLE_BEGIN => GC_CYCLE_START.with(|start| {
            start.set(Some(Instant::now()));
            println!("GC cycle began");
        }),
        GCProgress::GC_SLICE_BEGIN => GC_SLICE_START.with(|start| {
            start.set(Some(Instant::now()));
            println!("GC slice began");
        }),
        GCProgress::GC_SLICE_END => GC_SLICE_START.with(|start| {
            let duration = start.get().unwrap().elapsed();
            start.set(None);
            println!("GC slice ended: duration={:?}", duration);
        }),
        GCProgress::GC_CYCLE_END => GC_CYCLE_START.with(|start| {
            let duration = start.get().unwrap().elapsed();
            start.set(None);
            println!("GC cycle ended: duration={:?}", duration);
        }),
    };
    if !desc.is_null() {
        let desc: &GCDescription = &*desc;
        let options = match desc.options_ {
            GCOptions::Normal => "Normal",
            GCOptions::Shrink => "Shrink",
            GCOptions::Shutdown => "Shutdown",
        };
        println!("  isZone={}, options={}", desc.isZone_, options);
    }
    let _ = stdout().flush();
}

#[allow(unsafe_code)]
unsafe extern "C" fn debug_gc_callback(
    _cx: *mut RawJSContext,
    status: JSGCStatus,
    _reason: GCReason,
    _data: *mut os::raw::c_void,
) {
    match status {
        JSGCStatus::JSGC_BEGIN => thread_state::enter(ThreadState::IN_GC),
        JSGCStatus::JSGC_END => thread_state::exit(ThreadState::IN_GC),
    }
}

#[allow(unsafe_code)]
unsafe extern "C" fn trace_rust_roots(tr: *mut JSTracer, _data: *mut os::raw::c_void) {
    if !runtime_is_alive() {
        return;
    }
    trace!("starting custom root handler");
    trace_thread(tr);
    trace_roots(tr);
    trace_refcounted_objects(tr);
    settings_stack::trace(tr);
    trace!("done custom root handler");
}

#[allow(unsafe_code)]
unsafe extern "C" fn servo_build_id(build_id: *mut BuildIdCharVector) -> bool {
    let servo_id = b"Servo\0";
    SetBuildId(build_id, servo_id[0] as *const c_char, servo_id.len())
}

#[allow(unsafe_code)]
#[cfg(feature = "debugmozjs")]
unsafe fn set_gc_zeal_options(cx: *mut RawJSContext) {
    use js::jsapi::SetGCZeal;

    let level = match pref!(js_mem_gc_zeal_level) {
        level @ 0..=14 => level as u8,
        _ => return,
    };
    let frequency = match pref!(js_mem_gc_zeal_frequency) {
        frequency if frequency >= 0 => frequency as u32,
        // https://searchfox.org/mozilla-esr128/source/js/public/GCAPI.h#1392
        _ => 5000,
    };
    SetGCZeal(cx, level, frequency);
}

#[allow(unsafe_code)]
#[cfg(not(feature = "debugmozjs"))]
unsafe fn set_gc_zeal_options(_: *mut RawJSContext) {}

pub(crate) use script_bindings::script_runtime::JSContext;

/// Extra methods for the JSContext type defined in script_bindings, when
/// the methods are only called by code in the script crate.
pub(crate) trait JSContextHelper {
    fn get_reports(&self, path_seg: String, ops: &mut MallocSizeOfOps) -> Vec<Report>;
}

impl JSContextHelper for JSContext {
    #[allow(unsafe_code)]
    fn get_reports(&self, path_seg: String, ops: &mut MallocSizeOfOps) -> Vec<Report> {
        MALLOC_SIZE_OF_OPS.with(|ops_tls| ops_tls.set(ops));
        let stats = unsafe {
            let mut stats = ::std::mem::zeroed();
            if !CollectServoSizes(**self, &mut stats, Some(get_size)) {
                return vec![];
            }
            stats
        };
        MALLOC_SIZE_OF_OPS.with(|ops| ops.set(ptr::null_mut()));

        let mut reports = vec![];
        let mut report = |mut path_suffix, kind, size| {
            let mut path = path![path_seg, "js"];
            path.append(&mut path_suffix);
            reports.push(Report { path, kind, size })
        };

        // A note about possibly confusing terminology: the JS GC "heap" is allocated via
        // mmap/VirtualAlloc, which means it's not on the malloc "heap", so we use
        // `ExplicitNonHeapSize` as its kind.
        report(
            path!["gc-heap", "used"],
            ReportKind::ExplicitNonHeapSize,
            stats.gcHeapUsed,
        );

        report(
            path!["gc-heap", "unused"],
            ReportKind::ExplicitNonHeapSize,
            stats.gcHeapUnused,
        );

        report(
            path!["gc-heap", "admin"],
            ReportKind::ExplicitNonHeapSize,
            stats.gcHeapAdmin,
        );

        report(
            path!["gc-heap", "decommitted"],
            ReportKind::ExplicitNonHeapSize,
            stats.gcHeapDecommitted,
        );

        // SpiderMonkey uses the system heap, not jemalloc.
        report(
            path!["malloc-heap"],
            ReportKind::ExplicitSystemHeapSize,
            stats.mallocHeap,
        );

        report(
            path!["non-heap"],
            ReportKind::ExplicitNonHeapSize,
            stats.nonHeap,
        );
        reports
    }
}

pub(crate) struct StreamConsumer(*mut JSStreamConsumer);

#[allow(unsafe_code)]
impl StreamConsumer {
    pub(crate) fn consume_chunk(&self, stream: &[u8]) -> bool {
        unsafe {
            let stream_ptr = stream.as_ptr();
            StreamConsumerConsumeChunk(self.0, stream_ptr, stream.len())
        }
    }

    pub(crate) fn stream_end(&self) {
        unsafe {
            StreamConsumerStreamEnd(self.0);
        }
    }

    pub(crate) fn stream_error(&self, error_code: usize) {
        unsafe {
            StreamConsumerStreamError(self.0, error_code);
        }
    }

    pub(crate) fn note_response_urls(
        &self,
        maybe_url: Option<String>,
        maybe_source_map_url: Option<String>,
    ) {
        unsafe {
            let maybe_url = maybe_url.map(|url| CString::new(url).unwrap());
            let maybe_source_map_url = maybe_source_map_url.map(|url| CString::new(url).unwrap());

            let maybe_url_param = match maybe_url.as_ref() {
                Some(url) => url.as_ptr(),
                None => ptr::null(),
            };
            let maybe_source_map_url_param = match maybe_source_map_url.as_ref() {
                Some(url) => url.as_ptr(),
                None => ptr::null(),
            };

            StreamConsumerNoteResponseURLs(self.0, maybe_url_param, maybe_source_map_url_param);
        }
    }
}

/// Implements the steps to compile webassembly response mentioned here
/// <https://webassembly.github.io/spec/web-api/#compile-a-potential-webassembly-response>
#[allow(unsafe_code)]
unsafe extern "C" fn consume_stream(
    _cx: *mut RawJSContext,
    obj: HandleObject,
    _mime_type: MimeType,
    _consumer: *mut JSStreamConsumer,
) -> bool {
    let cx = JSContext::from_ptr(_cx);
    let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
    let global = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));

    // Step 2.1 Upon fulfillment of source, store the Response with value unwrappedSource.
    if let Ok(unwrapped_source) =
        root_from_handleobject::<Response>(RustHandleObject::from_raw(obj), *cx)
    {
        // Step 2.2 Let mimeType be the result of extracting a MIME type from response’s header list.
        let mimetype = unwrapped_source.Headers(CanGc::note()).extract_mime_type();

        // Step 2.3 If mimeType is not `application/wasm`, return with a TypeError and abort these substeps.
        if !&mimetype[..].eq_ignore_ascii_case(b"application/wasm") {
            throw_dom_exception(
                cx,
                &global,
                Error::Type("Response has unsupported MIME type".to_string()),
                CanGc::note(),
            );
            return false;
        }

        // Step 2.4 If response is not CORS-same-origin, return with a TypeError and abort these substeps.
        match unwrapped_source.Type() {
            DOMResponseType::Basic | DOMResponseType::Cors | DOMResponseType::Default => {},
            _ => {
                throw_dom_exception(
                    cx,
                    &global,
                    Error::Type("Response.type must be 'basic', 'cors' or 'default'".to_string()),
                    CanGc::note(),
                );
                return false;
            },
        }

        // Step 2.5 If response’s status is not an ok status, return with a TypeError and abort these substeps.
        if !unwrapped_source.Ok() {
            throw_dom_exception(
                cx,
                &global,
                Error::Type("Response does not have ok status".to_string()),
                CanGc::note(),
            );
            return false;
        }

        // Step 2.6.1 If response body is locked, return with a TypeError and abort these substeps.
        if unwrapped_source.is_locked() {
            throw_dom_exception(
                cx,
                &global,
                Error::Type("There was an error consuming the Response".to_string()),
                CanGc::note(),
            );
            return false;
        }

        // Step 2.6.2 If response body is alreaady consumed, return with a TypeError and abort these substeps.
        if unwrapped_source.is_disturbed() {
            throw_dom_exception(
                cx,
                &global,
                Error::Type("Response already consumed".to_string()),
                CanGc::note(),
            );
            return false;
        }
        unwrapped_source.set_stream_consumer(Some(StreamConsumer(_consumer)));
    } else {
        // Step 3 Upon rejection of source, return with reason.
        throw_dom_exception(
            cx,
            &global,
            Error::Type("expected Response or Promise resolving to Response".to_string()),
            CanGc::note(),
        );
        return false;
    }
    true
}

#[allow(unsafe_code)]
unsafe extern "C" fn report_stream_error(_cx: *mut RawJSContext, error_code: usize) {
    error!(
        "Error initializing StreamConsumer: {:?}",
        RUST_js_GetErrorMessage(ptr::null_mut(), error_code as u32)
    );
}

pub(crate) struct Runnable(*mut DispatchablePointer);

#[allow(unsafe_code)]
unsafe impl Sync for Runnable {}
#[allow(unsafe_code)]
unsafe impl Send for Runnable {}

#[allow(unsafe_code)]
impl Runnable {
    fn run(&self, cx: *mut RawJSContext, maybe_shutting_down: Dispatchable_MaybeShuttingDown) {
        unsafe {
            DispatchableRun(cx, self.0, maybe_shutting_down);
        }
    }
}

pub(crate) use script_bindings::script_runtime::CanGc;

/// `introductionType` values in SpiderMonkey TransitiveCompileOptions.
///
/// Value definitions are based on the SpiderMonkey Debugger API docs:
/// <https://firefox-source-docs.mozilla.org/js/Debugger/Debugger.Source.html#introductiontype>
// TODO: squish `scriptElement` <https://searchfox.org/mozilla-central/rev/202069c4c5113a1a9052d84fa4679d4c1b22113e/devtools/server/actors/source.js#199-201>
pub(crate) struct IntroductionType;
impl IntroductionType {
    /// `introductionType` for code passed to `eval`.
    pub const EVAL: &CStr = c"eval";
    pub const EVAL_STR: &str = "eval";

    /// `introductionType` for code evaluated by debugger.
    /// This includes code run via the devtools repl, even if the thread is not paused.
    pub const DEBUGGER_EVAL: &CStr = c"debugger eval";
    pub const DEBUGGER_EVAL_STR: &str = "debugger eval";

    /// `introductionType` for code passed to the `Function` constructor.
    pub const FUNCTION: &CStr = c"Function";
    pub const FUNCTION_STR: &str = "Function";

    /// `introductionType` for code loaded by worklet.
    pub const WORKLET: &CStr = c"Worklet";
    pub const WORKLET_STR: &str = "Worklet";

    /// `introductionType` for code assigned to DOM elements’ event handler IDL attributes as a string.
    pub const EVENT_HANDLER: &CStr = c"eventHandler";
    pub const EVENT_HANDLER_STR: &str = "eventHandler";

    /// `introductionType` for code belonging to `<script src="file.js">` elements.
    /// This includes `<script type="module" src="...">`.
    pub const SRC_SCRIPT: &CStr = c"srcScript";
    pub const SRC_SCRIPT_STR: &str = "srcScript";

    /// `introductionType` for code belonging to `<script>code;</script>` elements.
    /// This includes `<script type="module" src="...">`.
    pub const INLINE_SCRIPT: &CStr = c"inlineScript";
    pub const INLINE_SCRIPT_STR: &str = "inlineScript";

    /// `introductionType` for code belonging to scripts that *would* be `"inlineScript"` except that they were not
    /// part of the initial file itself.
    /// For example, scripts created via:
    /// - `document.write("<script>code;</script>")`
    /// - `var s = document.createElement("script"); s.text = "code";`
    pub const INJECTED_SCRIPT: &CStr = c"injectedScript";
    pub const INJECTED_SCRIPT_STR: &str = "injectedScript";

    /// `introductionType` for code that was loaded indirectly by being imported by another script
    /// using ESM static or dynamic imports.
    pub const IMPORTED_MODULE: &CStr = c"importedModule";
    pub const IMPORTED_MODULE_STR: &str = "importedModule";

    /// `introductionType` for code presented in `javascript:` URLs.
    pub const JAVASCRIPT_URL: &CStr = c"javascriptURL";
    pub const JAVASCRIPT_URL_STR: &str = "javascriptURL";

    /// `introductionType` for code passed to `setTimeout`/`setInterval` as a string.
    pub const DOM_TIMER: &CStr = c"domTimer";
    pub const DOM_TIMER_STR: &str = "domTimer";

    /// `introductionType` for web workers.
    /// FIXME: only documented in older(?) devtools user docs
    /// <https://firefox-source-docs.mozilla.org/devtools-user/debugger-api/debugger.source/index.html>
    pub const WORKER: &CStr = c"Worker";
    pub const WORKER_STR: &str = "Worker";
}
