Auto merge of #27365 - jdm:offthread-fixes, r=cybai

Fixes for off-thread compilation of scripts

Fixes #27355. Fixes #27349.
This commit is contained in:
bors-servo 2020-07-22 22:30:52 -04:00 committed by GitHub
commit 7b01d40a64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 44 deletions

View file

@ -86,14 +86,14 @@ use js::jsapi::Compile1;
use js::jsapi::SetScriptPrivate; use js::jsapi::SetScriptPrivate;
use js::jsapi::{CurrentGlobalOrNull, GetNonCCWObjectGlobal}; use js::jsapi::{CurrentGlobalOrNull, GetNonCCWObjectGlobal};
use js::jsapi::{HandleObject, Heap}; use js::jsapi::{HandleObject, Heap};
use js::jsapi::{JSContext, JSObject}; use js::jsapi::{JSContext, JSObject, JSScript};
use js::jsval::PrivateValue; use js::jsval::PrivateValue;
use js::jsval::{JSVal, UndefinedValue}; use js::jsval::{JSVal, UndefinedValue};
use js::panic::maybe_resume_unwind; use js::panic::maybe_resume_unwind;
use js::rust::transform_str_to_source_text; use js::rust::transform_str_to_source_text;
use js::rust::wrappers::{JS_ExecuteScript, JS_ExecuteScript1, JS_GetScriptPrivate}; use js::rust::wrappers::{JS_ExecuteScript, JS_GetScriptPrivate};
use js::rust::{get_object_class, CompileOptionsWrapper, ParentRuntime, Runtime}; use js::rust::{get_object_class, CompileOptionsWrapper, ParentRuntime, Runtime};
use js::rust::{HandleScript, HandleValue, MutableHandleValue}; use js::rust::{HandleValue, MutableHandleValue};
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL}; use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
use msg::constellation_msg::{ use msg::constellation_msg::{
BlobId, BroadcastChannelRouterId, MessagePortId, MessagePortRouterId, PipelineId, BlobId, BroadcastChannelRouterId, MessagePortId, MessagePortRouterId, PipelineId,
@ -2596,59 +2596,57 @@ impl GlobalScope {
let _aes = AutoEntryScript::new(self); let _aes = AutoEntryScript::new(self);
unsafe { unsafe {
let result = match code { rooted!(in(*cx) let mut compiled_script = std::ptr::null_mut::<JSScript>());
match code {
SourceCode::Text(text_code) => { SourceCode::Text(text_code) => {
let options = let options =
CompileOptionsWrapper::new(*cx, filename.as_ptr(), line_number); CompileOptionsWrapper::new(*cx, filename.as_ptr(), line_number);
debug!("compiling Dom string"); debug!("compiling dom string");
rooted!(in(*cx) let compiled_script = compiled_script.set(Compile1(
Compile1( *cx,
*cx, options.ptr,
options.ptr, &mut transform_str_to_source_text(text_code),
&mut transform_str_to_source_text(text_code), ));
)
);
if compiled_script.is_null() { if compiled_script.is_null() {
debug!("error compiling Dom string"); debug!("error compiling Dom string");
report_pending_exception(*cx, true, InRealm::Entered(&ar)); report_pending_exception(*cx, true, InRealm::Entered(&ar));
return false; return false;
} }
rooted!(in(*cx) let mut script_private = UndefinedValue());
JS_GetScriptPrivate(*compiled_script, script_private.handle_mut());
// When `ScriptPrivate` for the compiled script is undefined,
// we need to set it so that it can be used in dynamic import context.
if script_private.is_undefined() {
debug!("Set script private for {}", script_base_url);
let module_script_data = Rc::new(ModuleScript::new(
script_base_url,
fetch_options,
// We can't initialize an module owner here because
// the executing context of script might be different
// from the dynamic import script's executing context.
None,
));
SetScriptPrivate(
*compiled_script,
&PrivateValue(Rc::into_raw(module_script_data) as *const _),
);
}
debug!("evaluating Dom string");
JS_ExecuteScript(*cx, compiled_script.handle(), rval)
}, },
SourceCode::Compiled(compiled_script) => { SourceCode::Compiled(pre_compiled_script) => {
let script = compiled_script.source_code.get(); compiled_script.set(pre_compiled_script.source_code.get());
let script_handle = HandleScript::new(&script);
JS_ExecuteScript1(*cx, script_handle)
}, },
}; };
assert!(!compiled_script.is_null());
rooted!(in(*cx) let mut script_private = UndefinedValue());
JS_GetScriptPrivate(*compiled_script, script_private.handle_mut());
// When `ScriptPrivate` for the compiled script is undefined,
// we need to set it so that it can be used in dynamic import context.
if script_private.is_undefined() {
debug!("Set script private for {}", script_base_url);
let module_script_data = Rc::new(ModuleScript::new(
script_base_url,
fetch_options,
// We can't initialize an module owner here because
// the executing context of script might be different
// from the dynamic import script's executing context.
None,
));
SetScriptPrivate(
*compiled_script,
&PrivateValue(Rc::into_raw(module_script_data) as *const _),
);
}
let result = JS_ExecuteScript(*cx, compiled_script.handle(), rval);
if !result { if !result {
debug!("error evaluating Dom string"); debug!("error evaluating Dom string");
report_pending_exception(*cx, true, InRealm::Entered(&ar)); report_pending_exception(*cx, true, InRealm::Entered(&ar));

View file

@ -58,6 +58,7 @@ use servo_config::pref;
use servo_url::ImmutableOrigin; use servo_url::ImmutableOrigin;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use std::cell::Cell; use std::cell::Cell;
use std::ffi::CString;
use std::fs::{create_dir_all, read_to_string, File}; use std::fs::{create_dir_all, read_to_string, File};
use std::io::{Read, Seek, Write}; use std::io::{Read, Seek, Write};
use std::mem::replace; use std::mem::replace;
@ -424,8 +425,8 @@ impl FetchResponseListener for ClassicContext {
let cx = global.get_cx(); let cx = global.get_cx();
let _ar = enter_realm(&*global); let _ar = enter_realm(&*global);
let options = let final_url_c_str = CString::new(final_url.as_str()).unwrap();
unsafe { CompileOptionsWrapper::new(*cx, final_url.as_str().as_ptr() as *const i8, 1) }; let options = unsafe { CompileOptionsWrapper::new(*cx, final_url_c_str.as_ptr(), 1) };
let can_compile_off_thread = pref!(dom.script.asynch) && let can_compile_off_thread = pref!(dom.script.asynch) &&
unsafe { CanCompileOffThread(*cx, options.ptr as *const _, source_text.len()) }; unsafe { CanCompileOffThread(*cx, options.ptr as *const _, source_text.len()) };