/* 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/. */

//! Machinery to initialise interface prototype objects and interface objects.

use std::convert::TryFrom;
use std::ffi::CStr;
use std::ptr;

use js::error::throw_type_error;
use js::glue::UncheckedUnwrapObject;
use js::jsapi::JS::CompartmentIterResult;
use js::jsapi::{
    CallArgs, CheckedUnwrapStatic, Compartment, CompartmentSpecifier, CurrentGlobalOrNull,
    GetFunctionRealm, GetNonCCWObjectGlobal, GetRealmGlobalOrNull, GetWellKnownSymbol,
    HandleObject as RawHandleObject, IsSharableCompartment, IsSystemCompartment,
    JS_AtomizeAndPinString, JS_GetFunctionObject, JS_GetProperty, JS_IterateCompartments,
    JS_NewFunction, JS_NewGlobalObject, JS_NewObject, JS_NewStringCopyN, JS_SetReservedSlot,
    JS_SetTrustedPrincipals, JS_WrapObject, JSAutoRealm, JSClass, JSClassOps, JSContext,
    JSFUN_CONSTRUCTOR, JSFunctionSpec, JSObject, JSPROP_ENUMERATE, JSPROP_PERMANENT,
    JSPROP_READONLY, JSPROP_RESOLVING, JSPropertySpec, JSString, JSTracer, ObjectOps,
    OnNewGlobalHookOption, SymbolCode, TrueHandleValue, Value, jsid,
};
use js::jsval::{JSVal, NullValue, PrivateValue};
use js::rust::wrappers::{
    JS_DefineProperty, JS_DefineProperty3, JS_DefineProperty4, JS_DefineProperty5,
    JS_DefinePropertyById5, JS_FireOnNewGlobalObject, JS_LinkConstructorAndPrototype,
    JS_NewObjectWithGivenProto, RUST_SYMBOL_TO_JSID,
};
use js::rust::{
    HandleObject, HandleValue, MutableHandleObject, RealmOptions, define_methods,
    define_properties, get_object_class, is_dom_class, maybe_wrap_object,
};
use servo_url::MutableOrigin;

use crate::DomTypes;
use crate::codegen::Globals::Globals;
use crate::codegen::PrototypeList;
use crate::constant::{ConstantSpec, define_constants};
use crate::conversions::{DOM_OBJECT_SLOT, get_dom_class};
use crate::guard::Guard;
use crate::principals::ServoJSPrincipals;
use crate::script_runtime::JSContext as SafeJSContext;
use crate::utils::{
    DOM_PROTOTYPE_SLOT, DOMJSClass, JSCLASS_DOM_GLOBAL, ProtoOrIfaceArray, get_proto_or_iface_array,
};

/// The class of a non-callback interface object.
#[derive(Clone, Copy)]
pub(crate) struct NonCallbackInterfaceObjectClass {
    /// The SpiderMonkey class structure.
    pub(crate) _class: JSClass,
    /// The prototype id of that interface, used in the hasInstance hook.
    pub(crate) _proto_id: PrototypeList::ID,
    /// The prototype depth of that interface, used in the hasInstance hook.
    pub(crate) _proto_depth: u16,
    /// The string representation of the object.
    pub(crate) representation: &'static [u8],
}

unsafe impl Sync for NonCallbackInterfaceObjectClass {}

impl NonCallbackInterfaceObjectClass {
    /// Create a new `NonCallbackInterfaceObjectClass` structure.
    pub(crate) const fn new(
        constructor_behavior: &'static InterfaceConstructorBehavior,
        string_rep: &'static [u8],
        proto_id: PrototypeList::ID,
        proto_depth: u16,
    ) -> NonCallbackInterfaceObjectClass {
        NonCallbackInterfaceObjectClass {
            _class: JSClass {
                name: c"Function".as_ptr(),
                flags: 0,
                cOps: &constructor_behavior.0,
                spec: 0 as *const _,
                ext: 0 as *const _,
                oOps: &OBJECT_OPS,
            },
            _proto_id: proto_id,
            _proto_depth: proto_depth,
            representation: string_rep,
        }
    }

    /// cast own reference to `JSClass` reference
    pub(crate) fn as_jsclass(&self) -> &JSClass {
        unsafe { &*(self as *const _ as *const JSClass) }
    }
}

/// A constructor class hook.
pub(crate) type ConstructorClassHook =
    unsafe extern "C" fn(cx: *mut JSContext, argc: u32, vp: *mut Value) -> bool;

/// The constructor behavior of a non-callback interface object.
pub(crate) struct InterfaceConstructorBehavior(JSClassOps);

impl InterfaceConstructorBehavior {
    /// An interface constructor that unconditionally throws a type error.
    pub(crate) const fn throw() -> Self {
        InterfaceConstructorBehavior(JSClassOps {
            addProperty: None,
            delProperty: None,
            enumerate: None,
            newEnumerate: None,
            resolve: None,
            mayResolve: None,
            finalize: None,
            call: Some(invalid_constructor),
            construct: Some(invalid_constructor),
            trace: None,
        })
    }

    /// An interface constructor that calls a native Rust function.
    pub(crate) const fn call(hook: ConstructorClassHook) -> Self {
        InterfaceConstructorBehavior(JSClassOps {
            addProperty: None,
            delProperty: None,
            enumerate: None,
            newEnumerate: None,
            resolve: None,
            mayResolve: None,
            finalize: None,
            call: Some(non_new_constructor),
            construct: Some(hook),
            trace: None,
        })
    }
}

/// A trace hook.
pub(crate) type TraceHook = unsafe extern "C" fn(trc: *mut JSTracer, obj: *mut JSObject);

/// Create a global object with the given class.
pub(crate) unsafe fn create_global_object<D: DomTypes>(
    cx: SafeJSContext,
    class: &'static JSClass,
    private: *const libc::c_void,
    trace: TraceHook,
    mut rval: MutableHandleObject,
    origin: &MutableOrigin,
    use_system_compartment: bool,
) {
    assert!(rval.is_null());

    let mut options = RealmOptions::default();
    options.creationOptions_.traceGlobal_ = Some(trace);
    options.creationOptions_.sharedMemoryAndAtomics_ = false;
    if use_system_compartment {
        options.creationOptions_.compSpec_ = CompartmentSpecifier::NewCompartmentAndZone;
        options.creationOptions_.__bindgen_anon_1.comp_ = std::ptr::null_mut();
    } else {
        select_compartment(cx, &mut options);
    }

    // “System or addon” principals control JIT policy (IsBaselineJitEnabled, IsIonEnabled) and WASM policy
    // (IsSimdPrivilegedContext, HasSupport). This is unrelated to the concept of “system” compartments, though WASM
    // HasSupport describes checking this flag as “check trusted principals”, which seems to be a mistake.
    // Servo currently creates all principals as non-system-or-addon principals.
    let principal = ServoJSPrincipals::new::<D>(origin);
    if use_system_compartment {
        // “System” compartments are those that have all “system” realms, which in turn are those that were
        // created with the runtime’s global “trusted” principals. This influences the IsSystemCompartment() check
        // in select_compartment() below [1], preventing compartment reuse in either direction between this global
        // and any globals created with `use_system_compartment` set to false.
        // [1] IsSystemCompartment() → Realm::isSystem() → Realm::isSystem_ → principals == trustedPrincipals()
        JS_SetTrustedPrincipals(*cx, principal.as_raw());
    }

    rval.set(JS_NewGlobalObject(
        *cx,
        class,
        principal.as_raw(),
        OnNewGlobalHookOption::DontFireOnNewGlobalHook,
        &*options,
    ));
    assert!(!rval.is_null());

    // Initialize the reserved slots before doing anything that can GC, to
    // avoid getting trace hooks called on a partially initialized object.
    let private_val = PrivateValue(private);
    JS_SetReservedSlot(rval.get(), DOM_OBJECT_SLOT, &private_val);
    let proto_array: Box<ProtoOrIfaceArray> =
        Box::new([ptr::null_mut::<JSObject>(); PrototypeList::PROTO_OR_IFACE_LENGTH]);
    let val = PrivateValue(Box::into_raw(proto_array) as *const libc::c_void);
    JS_SetReservedSlot(rval.get(), DOM_PROTOTYPE_SLOT, &val);

    let _ac = JSAutoRealm::new(*cx, rval.get());
    JS_FireOnNewGlobalObject(*cx, rval.handle());
}

/// Choose the compartment to create a new global object in.
fn select_compartment(cx: SafeJSContext, options: &mut RealmOptions) {
    type Data = *mut Compartment;
    unsafe extern "C" fn callback(
        _cx: *mut JSContext,
        data: *mut libc::c_void,
        compartment: *mut Compartment,
    ) -> CompartmentIterResult {
        let data = data as *mut Data;

        if !IsSharableCompartment(compartment) || IsSystemCompartment(compartment) {
            return CompartmentIterResult::KeepGoing;
        }

        // Choose any sharable, non-system compartment in this context to allow
        // same-agent documents to share JS and DOM objects.
        *data = compartment;
        CompartmentIterResult::Stop
    }

    let mut compartment: Data = ptr::null_mut();
    unsafe {
        JS_IterateCompartments(
            *cx,
            (&mut compartment) as *mut Data as *mut libc::c_void,
            Some(callback),
        );
    }

    if compartment.is_null() {
        options.creationOptions_.compSpec_ = CompartmentSpecifier::NewCompartmentAndZone;
    } else {
        options.creationOptions_.compSpec_ = CompartmentSpecifier::ExistingCompartment;
        options.creationOptions_.__bindgen_anon_1.comp_ = compartment;
    }
}

/// Create and define the interface object of a callback interface.
pub(crate) fn create_callback_interface_object<D: DomTypes>(
    cx: SafeJSContext,
    global: HandleObject,
    constants: &[Guard<&[ConstantSpec]>],
    name: &CStr,
    mut rval: MutableHandleObject,
) {
    assert!(!constants.is_empty());
    unsafe {
        rval.set(JS_NewObject(*cx, ptr::null()));
    }
    assert!(!rval.is_null());
    define_guarded_constants::<D>(cx, rval.handle(), constants, global);
    define_name(cx, rval.handle(), name);
    define_on_global_object(cx, global, name, rval.handle());
}

/// Create the interface prototype object of a non-callback interface.
#[allow(clippy::too_many_arguments)]
pub(crate) fn create_interface_prototype_object<D: DomTypes>(
    cx: SafeJSContext,
    global: HandleObject,
    proto: HandleObject,
    class: &'static JSClass,
    regular_methods: &[Guard<&'static [JSFunctionSpec]>],
    regular_properties: &[Guard<&'static [JSPropertySpec]>],
    constants: &[Guard<&[ConstantSpec]>],
    unscopable_names: &[&CStr],
    mut rval: MutableHandleObject,
) {
    create_object::<D>(
        cx,
        global,
        proto,
        class,
        regular_methods,
        regular_properties,
        constants,
        rval.reborrow(),
    );

    if !unscopable_names.is_empty() {
        rooted!(in(*cx) let mut unscopable_obj = ptr::null_mut::<JSObject>());
        create_unscopable_object(cx, unscopable_names, unscopable_obj.handle_mut());
        unsafe {
            let unscopable_symbol = GetWellKnownSymbol(*cx, SymbolCode::unscopables);
            assert!(!unscopable_symbol.is_null());

            rooted!(in(*cx) let mut unscopable_id: jsid);
            RUST_SYMBOL_TO_JSID(unscopable_symbol, unscopable_id.handle_mut());

            assert!(JS_DefinePropertyById5(
                *cx,
                rval.handle(),
                unscopable_id.handle(),
                unscopable_obj.handle(),
                JSPROP_READONLY as u32
            ))
        }
    }
}

/// Create and define the interface object of a non-callback interface.
#[allow(clippy::too_many_arguments)]
pub(crate) fn create_noncallback_interface_object<D: DomTypes>(
    cx: SafeJSContext,
    global: HandleObject,
    proto: HandleObject,
    class: &'static NonCallbackInterfaceObjectClass,
    static_methods: &[Guard<&'static [JSFunctionSpec]>],
    static_properties: &[Guard<&'static [JSPropertySpec]>],
    constants: &[Guard<&[ConstantSpec]>],
    interface_prototype_object: HandleObject,
    name: &CStr,
    length: u32,
    legacy_window_alias_names: &[&CStr],
    mut rval: MutableHandleObject,
) {
    create_object::<D>(
        cx,
        global,
        proto,
        class.as_jsclass(),
        static_methods,
        static_properties,
        constants,
        rval.reborrow(),
    );
    unsafe {
        assert!(JS_LinkConstructorAndPrototype(
            *cx,
            rval.handle(),
            interface_prototype_object
        ));
    }
    define_name(cx, rval.handle(), name);
    define_length(cx, rval.handle(), i32::try_from(length).expect("overflow"));
    define_on_global_object(cx, global, name, rval.handle());

    if is_exposed_in(global, Globals::WINDOW) {
        for legacy_window_alias in legacy_window_alias_names {
            define_on_global_object(cx, global, legacy_window_alias, rval.handle());
        }
    }
}

/// Create and define the named constructors of a non-callback interface.
pub(crate) fn create_named_constructors(
    cx: SafeJSContext,
    global: HandleObject,
    named_constructors: &[(ConstructorClassHook, &CStr, u32)],
    interface_prototype_object: HandleObject,
) {
    rooted!(in(*cx) let mut constructor = ptr::null_mut::<JSObject>());

    for &(native, name, arity) in named_constructors {
        unsafe {
            let fun = JS_NewFunction(*cx, Some(native), arity, JSFUN_CONSTRUCTOR, name.as_ptr());
            assert!(!fun.is_null());
            constructor.set(JS_GetFunctionObject(fun));
            assert!(!constructor.is_null());

            assert!(JS_DefineProperty3(
                *cx,
                constructor.handle(),
                c"prototype".as_ptr(),
                interface_prototype_object,
                (JSPROP_PERMANENT | JSPROP_READONLY) as u32
            ));
        }

        define_on_global_object(cx, global, name, constructor.handle());
    }
}

/// Create a new object with a unique type.
#[allow(clippy::too_many_arguments)]
pub(crate) fn create_object<D: DomTypes>(
    cx: SafeJSContext,
    global: HandleObject,
    proto: HandleObject,
    class: &'static JSClass,
    methods: &[Guard<&'static [JSFunctionSpec]>],
    properties: &[Guard<&'static [JSPropertySpec]>],
    constants: &[Guard<&[ConstantSpec]>],
    mut rval: MutableHandleObject,
) {
    unsafe {
        rval.set(JS_NewObjectWithGivenProto(*cx, class, proto));
    }
    assert!(!rval.is_null());
    define_guarded_methods::<D>(cx, rval.handle(), methods, global);
    define_guarded_properties::<D>(cx, rval.handle(), properties, global);
    define_guarded_constants::<D>(cx, rval.handle(), constants, global);
}

/// Conditionally define constants on an object.
pub(crate) fn define_guarded_constants<D: DomTypes>(
    cx: SafeJSContext,
    obj: HandleObject,
    constants: &[Guard<&[ConstantSpec]>],
    global: HandleObject,
) {
    for guard in constants {
        if let Some(specs) = guard.expose::<D>(cx, obj, global) {
            define_constants(cx, obj, specs);
        }
    }
}

/// Conditionally define methods on an object.
pub(crate) fn define_guarded_methods<D: DomTypes>(
    cx: SafeJSContext,
    obj: HandleObject,
    methods: &[Guard<&'static [JSFunctionSpec]>],
    global: HandleObject,
) {
    for guard in methods {
        if let Some(specs) = guard.expose::<D>(cx, obj, global) {
            unsafe {
                define_methods(*cx, obj, specs).unwrap();
            }
        }
    }
}

/// Conditionally define properties on an object.
pub(crate) fn define_guarded_properties<D: DomTypes>(
    cx: SafeJSContext,
    obj: HandleObject,
    properties: &[Guard<&'static [JSPropertySpec]>],
    global: HandleObject,
) {
    for guard in properties {
        if let Some(specs) = guard.expose::<D>(cx, obj, global) {
            unsafe {
                define_properties(*cx, obj, specs).unwrap();
            }
        }
    }
}

/// Returns whether an interface with exposure set given by `globals` should
/// be exposed in the global object `obj`.
pub(crate) fn is_exposed_in(object: HandleObject, globals: Globals) -> bool {
    unsafe {
        let unwrapped = UncheckedUnwrapObject(object.get(), /* stopAtWindowProxy = */ false);
        let dom_class = get_dom_class(unwrapped).unwrap();
        globals.contains(dom_class.global)
    }
}

/// Define a property with a given name on the global object. Should be called
/// through the resolve hook.
pub(crate) fn define_on_global_object(
    cx: SafeJSContext,
    global: HandleObject,
    name: &CStr,
    obj: HandleObject,
) {
    unsafe {
        assert!(JS_DefineProperty3(
            *cx,
            global,
            name.as_ptr(),
            obj,
            JSPROP_RESOLVING
        ));
    }
}

const OBJECT_OPS: ObjectOps = ObjectOps {
    lookupProperty: None,
    defineProperty: None,
    hasProperty: None,
    getProperty: None,
    setProperty: None,
    getOwnPropertyDescriptor: None,
    deleteProperty: None,
    getElements: None,
    funToString: Some(fun_to_string_hook),
};

unsafe extern "C" fn fun_to_string_hook(
    cx: *mut JSContext,
    obj: RawHandleObject,
    _is_to_source: bool,
) -> *mut JSString {
    let js_class = get_object_class(obj.get());
    assert!(!js_class.is_null());
    let repr = (*(js_class as *const NonCallbackInterfaceObjectClass)).representation;
    assert!(!repr.is_empty());
    let ret = JS_NewStringCopyN(cx, repr.as_ptr() as *const libc::c_char, repr.len());
    assert!(!ret.is_null());
    ret
}

fn create_unscopable_object(cx: SafeJSContext, names: &[&CStr], mut rval: MutableHandleObject) {
    assert!(!names.is_empty());
    assert!(rval.is_null());
    unsafe {
        rval.set(JS_NewObjectWithGivenProto(
            *cx,
            ptr::null(),
            HandleObject::null(),
        ));
        assert!(!rval.is_null());
        for &name in names {
            assert!(JS_DefineProperty(
                *cx,
                rval.handle(),
                name.as_ptr(),
                HandleValue::from_raw(TrueHandleValue),
                JSPROP_ENUMERATE as u32,
            ));
        }
    }
}

fn define_name(cx: SafeJSContext, obj: HandleObject, name: &CStr) {
    unsafe {
        rooted!(in(*cx) let name = JS_AtomizeAndPinString(*cx, name.as_ptr()));
        assert!(!name.is_null());
        assert!(JS_DefineProperty4(
            *cx,
            obj,
            c"name".as_ptr(),
            name.handle(),
            JSPROP_READONLY as u32
        ));
    }
}

fn define_length(cx: SafeJSContext, obj: HandleObject, length: i32) {
    unsafe {
        assert!(JS_DefineProperty5(
            *cx,
            obj,
            c"length".as_ptr(),
            length,
            JSPROP_READONLY as u32
        ));
    }
}

unsafe extern "C" fn invalid_constructor(
    cx: *mut JSContext,
    _argc: libc::c_uint,
    _vp: *mut JSVal,
) -> bool {
    throw_type_error(cx, "Illegal constructor.");
    false
}

unsafe extern "C" fn non_new_constructor(
    cx: *mut JSContext,
    _argc: libc::c_uint,
    _vp: *mut JSVal,
) -> bool {
    throw_type_error(cx, "This constructor needs to be called with `new`.");
    false
}

pub(crate) enum ProtoOrIfaceIndex {
    ID(PrototypeList::ID),
    Constructor(PrototypeList::Constructor),
}

impl From<ProtoOrIfaceIndex> for usize {
    fn from(index: ProtoOrIfaceIndex) -> usize {
        match index {
            ProtoOrIfaceIndex::ID(id) => id as usize,
            ProtoOrIfaceIndex::Constructor(constructor) => constructor as usize,
        }
    }
}

pub(crate) fn get_per_interface_object_handle(
    cx: SafeJSContext,
    global: HandleObject,
    id: ProtoOrIfaceIndex,
    creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
    mut rval: MutableHandleObject,
) {
    unsafe {
        assert!(((*get_object_class(global.get())).flags & JSCLASS_DOM_GLOBAL) != 0);

        /* Check to see whether the interface objects are already installed */
        let proto_or_iface_array = get_proto_or_iface_array(global.get());
        let index: usize = id.into();
        rval.set((*proto_or_iface_array)[index]);
        if !rval.get().is_null() {
            return;
        }

        creator(cx, global, proto_or_iface_array);
        rval.set((*proto_or_iface_array)[index]);
        assert!(!rval.get().is_null());
    }
}

pub(crate) fn define_dom_interface(
    cx: SafeJSContext,
    global: HandleObject,
    id: ProtoOrIfaceIndex,
    creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
    enabled: fn(SafeJSContext, HandleObject) -> bool,
) {
    assert!(!global.get().is_null());

    if !enabled(cx, global) {
        return;
    }

    rooted!(in(*cx) let mut proto = ptr::null_mut::<JSObject>());
    get_per_interface_object_handle(cx, global, id, creator, proto.handle_mut());
    assert!(!proto.is_null());
}

fn get_proto_id_for_new_target(new_target: HandleObject) -> Option<PrototypeList::ID> {
    unsafe {
        let new_target_class = get_object_class(*new_target);
        if is_dom_class(&*new_target_class) {
            let domjsclass: *const DOMJSClass = new_target_class as *const DOMJSClass;
            let dom_class = &(*domjsclass).dom_class;
            return Some(dom_class.interface_chain[dom_class.depth as usize]);
        }
        None
    }
}

#[allow(clippy::result_unit_err)]
pub fn get_desired_proto(
    cx: SafeJSContext,
    args: &CallArgs,
    proto_id: PrototypeList::ID,
    creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
    mut desired_proto: MutableHandleObject,
) -> Result<(), ()> {
    unsafe {
        // This basically implements
        // https://heycam.github.io/webidl/#internally-create-a-new-object-implementing-the-interface
        // step 3.

        assert!(args.is_constructing());

        // The desired prototype depends on the actual constructor that was invoked,
        // which is passed to us as the newTarget in the callargs.  We want to do
        // something akin to the ES6 specification's GetProtototypeFromConstructor (so
        // get .prototype on the newTarget, with a fallback to some sort of default).

        // First, a fast path for the case when the the constructor is in fact one of
        // our DOM constructors.  This is safe because on those the "constructor"
        // property is non-configurable and non-writable, so we don't have to do the
        // slow JS_GetProperty call.
        rooted!(in(*cx) let mut new_target = args.new_target().to_object());
        rooted!(in(*cx) let original_new_target = *new_target);
        // See whether we have a known DOM constructor here, such that we can take a
        // fast path.
        let target_proto_id = get_proto_id_for_new_target(new_target.handle()).or_else(|| {
            // We might still have a cross-compartment wrapper for a known DOM
            // constructor.  CheckedUnwrapStatic is fine here, because we're looking for
            // DOM constructors and those can't be cross-origin objects.
            new_target.set(CheckedUnwrapStatic(*new_target));
            if !new_target.is_null() && *new_target != *original_new_target {
                get_proto_id_for_new_target(new_target.handle())
            } else {
                None
            }
        });

        if let Some(proto_id) = target_proto_id {
            let global = GetNonCCWObjectGlobal(*new_target);
            let proto_or_iface_cache = get_proto_or_iface_array(global);
            desired_proto.set((*proto_or_iface_cache)[proto_id as usize]);
            if *new_target != *original_new_target && !JS_WrapObject(*cx, desired_proto.into()) {
                return Err(());
            }
            return Ok(());
        }

        // Slow path.  This basically duplicates the ES6 spec's
        // GetPrototypeFromConstructor except that instead of taking a string naming
        // the fallback prototype we determine the fallback based on the proto id we
        // were handed.
        rooted!(in(*cx) let mut proto_val = NullValue());
        if !JS_GetProperty(
            *cx,
            original_new_target.handle().into(),
            c"prototype".as_ptr(),
            proto_val.handle_mut().into(),
        ) {
            return Err(());
        }

        if proto_val.is_object() {
            desired_proto.set(proto_val.to_object());
            return Ok(());
        }

        // Fall back to getting the proto for our given proto id in the realm that
        // GetFunctionRealm(newTarget) returns.
        let realm = GetFunctionRealm(*cx, new_target.handle().into());

        if realm.is_null() {
            return Err(());
        }

        {
            let _realm = JSAutoRealm::new(*cx, GetRealmGlobalOrNull(realm));
            rooted!(in(*cx) let global = CurrentGlobalOrNull(*cx));
            get_per_interface_object_handle(
                cx,
                global.handle(),
                ProtoOrIfaceIndex::ID(proto_id),
                creator,
                desired_proto.reborrow(),
            );
            if desired_proto.is_null() {
                return Err(());
            }
        }

        maybe_wrap_object(*cx, desired_proto);
        Ok(())
    }
}
