/
githubmirror
/
servo
Обзор
Документация
Войти
/
githubmirror
/
servo
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
components/devtools/actors/breakpoint.rs
153 строки
5 KB
eri
devtools: Avoid panics when borrowing in `ActorRegistry` (#45248)
04 июн 2026, 13:57
Не верифицирован
04 июн 2026, 13:57
84fa008
Код
Авторство
О чём код?
/* 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/. */ use std::sync::Arc; use devtools_traits::DevtoolScriptControlMsg; use malloc_size_of_derive::MallocSizeOf; use serde::Deserialize; use serde_json::Map; use crate::actor::{Actor, ActorEncode, ActorError, ActorRegistry, new_actor_name}; use crate::actors::browsing_context::BrowsingContextActor; use crate::actors::thread::ThreadActor; use crate::protocol::ClientRequest; use crate::{ActorMsg, EmptyReplyMsg}; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct BreakpointRequestLocation { pub line: u32, pub column: u32, #[serde(skip_serializing_if = "Option::is_none")] pub source_url: Option<String>, } #[derive(Deserialize)] struct BreakpointRequest { location: BreakpointRequestLocation, } #[derive(MallocSizeOf)] pub(crate) struct BreakpointListActor { name: String, browsing_context_name: String, } impl Actor for BreakpointListActor { fn name(&self) -> &str { &self.name } fn handle_message( &self, request: ClientRequest, registry: &crate::actor::ActorRegistry, msg_type: &str, msg: &Map<String, serde_json::Value>, _stream_id: crate::StreamId, ) -> Result<(), ActorError> { match msg_type { // Client wants to set a breakpoint. // Seems to be infallible, unlike the thread actor’s `setBreakpoint`. // <https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html#breakpoints> "setBreakpoint" => { let msg: BreakpointRequest = serde_json::from_value(msg.clone().into()).map_err(|_| ActorError::Internal)?; let BreakpointRequestLocation { line, column, source_url, } = msg.location; let source_url = source_url.ok_or(ActorError::Internal)?; let browsing_context_actor = registry.find::<BrowsingContextActor>(&self.browsing_context_name); let thread_actor = registry.find::<ThreadActor>(&browsing_context_actor.thread_name); let source = thread_actor .source_manager .find_source(registry, &source_url) .ok_or(ActorError::Internal)?; if let Some((script_id, offset)) = source.find_offset(line, column) { source .script_sender .send(DevtoolScriptControlMsg::SetBreakpoint( source.spidermonkey_id, script_id, offset, )) .map_err(|_| ActorError::Internal)?; } let msg = EmptyReplyMsg { from: self.name().into(), }; request.reply_final(&msg)? }, "setActiveEventBreakpoints" => { let msg = EmptyReplyMsg { from: self.name().into(), }; request.reply_final(&msg)? }, "removeBreakpoint" => { let msg: BreakpointRequest = serde_json::from_value(msg.clone().into()).map_err(|_| ActorError::Internal)?; let BreakpointRequestLocation { line, column, source_url, } = msg.location; let source_url = source_url.ok_or(ActorError::Internal)?; let browsing_context_actor = registry.find::<BrowsingContextActor>(&self.browsing_context_name); let thread_actor = registry.find::<ThreadActor>(&browsing_context_actor.thread_name); let source = thread_actor .source_manager .find_source(registry, &source_url) .ok_or(ActorError::Internal)?; if let Some((script_id, offset)) = source.find_offset(line, column) { source .script_sender .send(DevtoolScriptControlMsg::ClearBreakpoint( source.spidermonkey_id, script_id, offset, )) .map_err(|_| ActorError::Internal)?; } let msg = EmptyReplyMsg { from: self.name().into(), }; request.reply_final(&msg)? }, _ => return Err(ActorError::UnrecognizedPacketType), }; Ok(()) } } impl BreakpointListActor { pub fn register(registry: &ActorRegistry, browsing_context_name: String) -> Arc<Self> { let name = new_actor_name::<Self>(); let actor = Self { name, browsing_context_name, }; registry.register::<Self>(actor) } } impl ActorEncode<ActorMsg> for BreakpointListActor { fn encode(&self, _: &ActorRegistry) -> ActorMsg { ActorMsg { actor: self.name().into(), } } }