Ensure compiled script module object remains rooted while it's being passed around. (#33938)

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2024-10-22 21:30:47 -04:00 committed by GitHub
parent 7fbd2a521e
commit 6fdd5ce4cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -29,7 +29,8 @@ use js::jsval::{JSVal, PrivateValue, UndefinedValue};
use js::rust::jsapi_wrapped::JS_GetPendingException; use js::rust::jsapi_wrapped::JS_GetPendingException;
use js::rust::wrappers::JS_SetPendingException; use js::rust::wrappers::JS_SetPendingException;
use js::rust::{ use js::rust::{
transform_str_to_source_text, CompileOptionsWrapper, Handle, HandleValue, IntoHandle, transform_str_to_source_text, CompileOptionsWrapper, Handle, HandleObject as RustHandleObject,
HandleValue, IntoHandle, MutableHandleObject as RustMutableHandleObject,
}; };
use mime::Mime; use mime::Mime;
use net_traits::http_status::HttpStatus; use net_traits::http_status::HttpStatus;
@ -87,6 +88,10 @@ unsafe fn gen_type_error(global: &GlobalScope, string: String) -> RethrowError {
pub struct ModuleObject(Box<Heap<*mut JSObject>>); pub struct ModuleObject(Box<Heap<*mut JSObject>>);
impl ModuleObject { impl ModuleObject {
fn new(obj: RustHandleObject) -> ModuleObject {
ModuleObject(Heap::boxed(obj.get()))
}
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn handle(&self) -> HandleObject { pub fn handle(&self) -> HandleObject {
unsafe { self.0.handle() } unsafe { self.0.handle() }
@ -426,14 +431,15 @@ impl ModuleTree {
module_script_text: Rc<DOMString>, module_script_text: Rc<DOMString>,
url: &ServoUrl, url: &ServoUrl,
options: ScriptFetchOptions, options: ScriptFetchOptions,
) -> Result<ModuleObject, RethrowError> { mut module_script: RustMutableHandleObject,
) -> Result<(), RethrowError> {
let cx = GlobalScope::get_cx(); let cx = GlobalScope::get_cx();
let _ac = JSAutoRealm::new(*cx, *global.reflector().get_jsobject()); let _ac = JSAutoRealm::new(*cx, *global.reflector().get_jsobject());
let compile_options = unsafe { CompileOptionsWrapper::new(*cx, url.as_str(), 1) }; let compile_options = unsafe { CompileOptionsWrapper::new(*cx, url.as_str(), 1) };
unsafe { unsafe {
rooted!(in(*cx) let mut module_script = CompileModule1( module_script.set(CompileModule1(
*cx, *cx,
compile_options.ptr, compile_options.ptr,
&mut transform_str_to_source_text(&module_script_text), &mut transform_str_to_source_text(&module_script_text),
@ -465,7 +471,7 @@ impl ModuleTree {
module_script.handle().into_handle(), module_script.handle().into_handle(),
url, url,
) )
.map(|_| ModuleObject(Heap::boxed(*module_script))) .map(|_| ())
} }
} }
@ -1161,21 +1167,24 @@ impl FetchResponseListener for ModuleContext {
Ok(ref resp_mod_script) => { Ok(ref resp_mod_script) => {
module_tree.set_text(resp_mod_script.text()); module_tree.set_text(resp_mod_script.text());
let compiled_module = module_tree.compile_module_script( let cx = GlobalScope::get_cx();
rooted!(in(*cx) let mut compiled_module: *mut JSObject = ptr::null_mut());
let compiled_module_result = module_tree.compile_module_script(
&global, &global,
self.owner.clone(), self.owner.clone(),
resp_mod_script.text(), resp_mod_script.text(),
&self.url, &self.url,
self.options.clone(), self.options.clone(),
compiled_module.handle_mut(),
); );
match compiled_module { match compiled_module_result {
Err(exception) => { Err(exception) => {
module_tree.set_rethrow_error(exception); module_tree.set_rethrow_error(exception);
module_tree.advance_finished_and_link(&global); module_tree.advance_finished_and_link(&global);
}, },
Ok(record) => { Ok(_) => {
module_tree.set_record(record); module_tree.set_record(ModuleObject::new(compiled_module.handle()));
module_tree.fetch_module_descendants( module_tree.fetch_module_descendants(
&self.owner, &self.owner,
@ -1728,23 +1737,26 @@ pub(crate) fn fetch_inline_module_script(
let is_external = false; let is_external = false;
let module_tree = ModuleTree::new(url.clone(), is_external, HashSet::new()); let module_tree = ModuleTree::new(url.clone(), is_external, HashSet::new());
let compiled_module = module_tree.compile_module_script( let cx = GlobalScope::get_cx();
rooted!(in(*cx) let mut compiled_module: *mut JSObject = ptr::null_mut());
let compiled_module_result = module_tree.compile_module_script(
&global, &global,
owner.clone(), owner.clone(),
module_script_text, module_script_text,
&url, &url,
options.clone(), options.clone(),
compiled_module.handle_mut(),
); );
match compiled_module { match compiled_module_result {
Ok(record) => { Ok(_) => {
module_tree.append_handler( module_tree.append_handler(
owner.clone(), owner.clone(),
ModuleIdentity::ScriptId(script_id), ModuleIdentity::ScriptId(script_id),
options.clone(), options.clone(),
can_gc, can_gc,
); );
module_tree.set_record(record); module_tree.set_record(ModuleObject::new(compiled_module.handle()));
// We need to set `module_tree` into inline module map in case // We need to set `module_tree` into inline module map in case
// of that the module descendants finished right after the // of that the module descendants finished right after the