Repository: servo/servo
File: components/script/devtools.rs (Rust)

Code before:
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeConstants;
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use crate::dom::bindings::conversions::{ConversionResult, FromJSValConvertible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::css::cssstyledeclaration::ENABLED_LONGHAND_PROPERTIES;
use crate::dom::css::cssstylerule::CSSStyleRule;
use crate::dom::document::AnimationFrameCallback;
use crate::dom::element::Element;
use crate::dom::globalscope::GlobalScope;
use crate::dom::node::{Node, NodeTraits, ShadowIncluding};
use crate::dom::types::{EventTarget, HTMLElement};
use crate::realms::{enter_auto_realm, enter_realm};
use crate::script_runtime::{CanGc, IntroductionType};

#[expect(unsafe_code)]
pub(crate) fn handle_evaluate_js(
    global: &GlobalScope,
    eval: String,
    reply: GenericSender<EvaluateJSReply>,
    cx: &mut JSContext,
) {
    let result = unsafe {
        let mut realm = enter_auto_realm(cx, global);
        let cx = &mut realm.current_realm();
        rooted!(&in(cx) let mut rval = UndefinedValue());
        // TODO: run code with SpiderMonkey Debugger API, like Firefox does
        // <https://searchfox.org/mozilla-central/rev/f6a806c38c459e0e0d797d264ca0e8ad46005105/devtools/server/actors/webconsole/eval-with-debugger.js#270>
        _ = global.evaluate_js_on_global(
            eval.into(),
            "<eval>",
            Some(IntroductionType::DEBUGGER_EVAL),
            rval.handle_mut(),
            CanGc::from_cx(cx),
        );

        if rval.is_undefined() {
            EvaluateJSReply::VoidValue
        } else if rval.is_boolean() {
            EvaluateJSReply::BooleanValue(rval.to_boolean())
        } else if rval.is_double() || rval.is_int32() {
            EvaluateJSReply::NumberValue(
                match FromJSValConvertible::from_jsval(cx.raw_cx(), rval.handle(), ()) {
                    Ok(ConversionResult::Success(v)) => v,
                    _ => unreachable!(),
                },
            )
        } else if rval.is_string() {
            let jsstr = std::ptr::NonNull::new(rval.to_string()).unwrap();
            EvaluateJSReply::StringValue(jsstr_to_string(cx.raw_cx(), jsstr))

Review comment (suggestion):
This is redundant as both CurrentRealm and AutoRealm deref into JSContext. Usually we just do this:
```suggestion
        let cx = &mut realm;
```
just to avoid writing `&mut` everywhere.

Code after:
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeConstants;
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use crate::dom::bindings::conversions::{ConversionResult, FromJSValConvertible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::css::cssstyledeclaration::ENABLED_LONGHAND_PROPERTIES;
use crate::dom::css::cssstylerule::CSSStyleRule;
use crate::dom::document::AnimationFrameCallback;
use crate::dom::element::Element;
use crate::dom::globalscope::GlobalScope;
use crate::dom::node::{Node, NodeTraits, ShadowIncluding};
use crate::dom::types::{EventTarget, HTMLElement};
use crate::realms::{enter_auto_realm, enter_realm};
use crate::script_runtime::{CanGc, IntroductionType};

#[expect(unsafe_code)]
pub(crate) fn handle_evaluate_js(
    global: &GlobalScope,
    eval: String,
    reply: GenericSender<EvaluateJSReply>,
    cx: &mut JSContext,
) {
    let result = unsafe {
        let mut realm = enter_auto_realm(cx, global);
        let cx = &mut realm;
        rooted!(&in(cx) let mut rval = UndefinedValue());
        // TODO: run code with SpiderMonkey Debugger API, like Firefox does
        // <https://searchfox.org/mozilla-central/rev/f6a806c38c459e0e0d797d264ca0e8ad46005105/devtools/server/actors/webconsole/eval-with-debugger.js#270>
        _ = global.evaluate_js_on_global(
            eval.into(),
            "<eval>",
            Some(IntroductionType::DEBUGGER_EVAL),
            rval.handle_mut(),
            CanGc::from_cx(cx),
        );

        if rval.is_undefined() {
            EvaluateJSReply::VoidValue
        } else if rval.is_boolean() {
            EvaluateJSReply::BooleanValue(rval.to_boolean())
        } else if rval.is_double() || rval.is_int32() {
            EvaluateJSReply::NumberValue(
                match FromJSValConvertible::from_jsval(cx.raw_cx(), rval.handle(), ()) {
                    Ok(ConversionResult::Success(v)) => v,
                    _ => unreachable!(),
                },
            )
        } else if rval.is_string() {
            let jsstr = std::ptr::NonNull::new(rval.to_string()).unwrap();
            EvaluateJSReply::StringValue(jsstr_to_string(cx.raw_cx(), jsstr))