Auto merge of #23544 - georgeroman:fix_borrow_mut_error_in_webdriver, r=asajeffrey

Fix already borrowed error in webdriver

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #23535

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23544)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2019-06-10 14:26:17 -04:00 committed by GitHub
commit b3eed5b5bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 41 deletions

View file

@ -1834,6 +1834,22 @@ impl ScriptThread {
}
fn handle_webdriver_msg(&self, pipeline_id: PipelineId, msg: WebDriverScriptCommand) {
// https://github.com/servo/servo/issues/23535
// These two messages need different treatment since the JS script might mutate
// `self.documents`, which would conflict with the immutable borrow of it that
// occurs for the rest of the messages
match msg {
WebDriverScriptCommand::ExecuteScript(script, reply) => {
let window = { self.documents.borrow().find_window(pipeline_id) };
return webdriver_handlers::handle_execute_script(window, script, reply);
},
WebDriverScriptCommand::ExecuteAsyncScript(script, reply) => {
let window = { self.documents.borrow().find_window(pipeline_id) };
return webdriver_handlers::handle_execute_async_script(window, script, reply);
},
_ => (),
}
let documents = self.documents.borrow();
match msg {
WebDriverScriptCommand::AddCookie(params, reply) => {
@ -1842,9 +1858,6 @@ impl ScriptThread {
WebDriverScriptCommand::DeleteCookies(reply) => {
webdriver_handlers::handle_delete_cookies(&*documents, pipeline_id, reply)
},
WebDriverScriptCommand::ExecuteScript(script, reply) => {
webdriver_handlers::handle_execute_script(&*documents, pipeline_id, script, reply)
},
WebDriverScriptCommand::FindElementCSS(selector, reply) => {
webdriver_handlers::handle_find_element_css(
&*documents,
@ -1937,14 +1950,7 @@ impl ScriptThread {
WebDriverScriptCommand::GetTitle(reply) => {
webdriver_handlers::handle_get_title(&*documents, pipeline_id, reply)
},
WebDriverScriptCommand::ExecuteAsyncScript(script, reply) => {
webdriver_handlers::handle_execute_async_script(
&*documents,
pipeline_id,
script,
reply,
)
},
_ => (),
}
}

View file

@ -23,6 +23,7 @@ use crate::dom::htmliframeelement::HTMLIFrameElement;
use crate::dom::htmlinputelement::HTMLInputElement;
use crate::dom::htmloptionelement::HTMLOptionElement;
use crate::dom::node::{window_from_node, Node, ShadowIncluding};
use crate::dom::window::Window;
use crate::script_thread::Documents;
use cookie::Cookie;
use euclid::{Point2D, Rect, Size2D};
@ -87,53 +88,51 @@ pub unsafe fn jsval_to_webdriver(cx: *mut JSContext, val: HandleValue) -> WebDri
#[allow(unsafe_code)]
pub fn handle_execute_script(
documents: &Documents,
pipeline: PipelineId,
window: Option<DomRoot<Window>>,
eval: String,
reply: IpcSender<WebDriverJSResult>,
) {
let window = match documents.find_window(pipeline) {
Some(window) => window,
match window {
Some(window) => {
let result = unsafe {
let cx = window.get_cx();
rooted!(in(cx) let mut rval = UndefinedValue());
window
.upcast::<GlobalScope>()
.evaluate_js_on_global_with_result(&eval, rval.handle_mut());
jsval_to_webdriver(cx, rval.handle())
};
reply.send(result).unwrap();
},
None => {
return reply
reply
.send(Err(WebDriverJSError::BrowsingContextNotFound))
.unwrap();
},
};
let result = unsafe {
let cx = window.get_cx();
rooted!(in(cx) let mut rval = UndefinedValue());
window
.upcast::<GlobalScope>()
.evaluate_js_on_global_with_result(&eval, rval.handle_mut());
jsval_to_webdriver(cx, rval.handle())
};
reply.send(result).unwrap();
}
}
pub fn handle_execute_async_script(
documents: &Documents,
pipeline: PipelineId,
window: Option<DomRoot<Window>>,
eval: String,
reply: IpcSender<WebDriverJSResult>,
) {
let window = match documents.find_window(pipeline) {
Some(window) => window,
match window {
Some(window) => {
let cx = window.get_cx();
window.set_webdriver_script_chan(Some(reply));
rooted!(in(cx) let mut rval = UndefinedValue());
window
.upcast::<GlobalScope>()
.evaluate_js_on_global_with_result(&eval, rval.handle_mut());
},
None => {
return reply
reply
.send(Err(WebDriverJSError::BrowsingContextNotFound))
.unwrap();
},
};
let cx = window.get_cx();
window.set_webdriver_script_chan(Some(reply));
rooted!(in(cx) let mut rval = UndefinedValue());
window
.upcast::<GlobalScope>()
.evaluate_js_on_global_with_result(&eval, rval.handle_mut());
}
}
pub fn handle_get_browsing_context_id(